爬取的基本原理是:使用代码控制浏览器,让浏览器加载出页面后,把页面的源代码抓取下来
这篇博客的思路是:
- 基本环境搭建
- 核心代码与解释
- 工具类的代码与解释
一. 基本环境搭建
这里建议使用豆瓣源进行安装,否则scrapy很可能超时
pip install -i https://pypi.douban.com/simple/ scrapy #主要是因为Selector对页面的解析速度会更快
pip install -i https://pypi.douban.com/simple/ selenium #主要的依赖包
二.核心代码与解释
from selenium import webdriver
from scrapy import Selector
from urllib.parse import urljoin
from utils.change_driver import change
from utils.save_html_page import save_html
import time
# ------------- 这个需要修改成目标网页 ---------------#
url_temp = "http://blog.csdn.net/weixin_35757704/article/list/"
# ------------- 这个是要爬取的页面数量 ---------------#
page_num = 5
# ------------- 接下来就是控制代码---------------- #
driver = webdriver.Chrome(executable_path='/home/...放置driver的路径.../chromedriver')
article_num = 0
# 遍历所有网页
for i in range(page_num):
list_url = url_temp + str(i + 1)
change(driver=driver, url=list_url)
time.sleep(5) # 休眠5s,建议不要抓取过快,对服务器不友好
selector = Selector(text=driver.page_source)
# 得到显示页面的列表
article_list = selector.css("div#article_list .article_item")
for article in article_list:
article_url = article.css(".article_title a ::attr(href)").extract_first()
change(driver=driver, url=urljoin(list_url, article_url))
time.sleep(5)
article_selector = Selector(text=driver.page_source)
title = article_selector.css("#article_details .article_title").extract_first()
content = article_selector.css("#article_details #article_content").extract_first()
content = title + content
# 把页面存在本地
save_html("detail{0}.html".format(str(article_num)), content=content)
article_num = article_num + 1
# 关闭这个标签
driver.close()
使用这份代码的时候要注意三点:
- 第一行url_temp需要修改成想要爬取的页面
- 第二行page_num设置为想要爬取的数量
- utils.chang_driver 与 utils.save_html_page 为工具包,下面的第三节中会有分析
这份代码的思路就是首先定位到目标作者的页面,也就是url_temp这个页面,然后截取页面中包含文章列表的部分,也就是下面的截图中的部分:
这样,就得到了包含列表信息的页面,然后从题目中抽取 <a> 标签的url,因为这个url使用的是相对地址,因此我们使用urllib.parse的urljoin,通过相对地址得到绝对地址(python3的位置,Python2中 : import urllib,使用urllib.urljoin)
然后使用selenium访问这个具体文章的url,比如:
然后把标题和内容抽取出来就OK了.
三.工具类代码与解释
1.utils.chang_driver
这个主要是方便打开标签页与标签页之间的转换
import time
def change(driver, url):
if driver is None or url is None:
return
url = url.strip()
# 将视角转到最后一个标签页
handles = driver.window_handles
driver.switch_to.window(handles[-1])
# 在新窗口打开url
script = 'window.open("{0}");'.format(url)
driver.execute_script(script)
# 再次将视角转到最后一个标签页
handles = driver.window_handles
driver.switch_to.window(handles[-1])
# 休眠2s,等待加载完成
time.sleep(2)
2.utils.save_html_page
这个类就是方便把从网页爬取到的内容保存下来.
def save_html(file_name='test.html', content="",
path='/home/....保存的路径.../html/'):
file = open(path + file_name, 'w')
file.write(content)
file.flush()
file.close()
file_name: 保存的文件名,注意加.html的后缀
content: 保存的内容
path: 保存的根路径