1. 新建知乎爬虫:
> scrapy genspider zhihu www.zhihu.com
编写zhihu spider的页面解析函数parse()
,由于此函数被要求返回一个可迭代对象,所以这里直接返回一个空列表作为测试。
# -*- coding: utf-8 -*-
# @Author : One Fine
# @File : zhihu.py
import scrapy
class ZhihuSpider(scrapy.Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['http://www.zhihu.com/']
def parse(self, response):
yield [] # 测试
注:这里重点介绍将Selenium集成到Scrapy中,关于zhihu spider的具体逻辑将忽略。
2.编写Downloader Middleware
先实现Downloader Middleware的process_request()
方法,当返回为Response对象(htmlResponse是其子类)时,Scrapy将不会调用任何其他的process_request方法,将直接返回这个response对象。
from selenium import webdriver
from time import sleep
from scrapy.http import HtmlResponse
class JSPageMiddleware(object):
# 通过Chrome请求动态网页
def __init__(self):
self.browser = webdriver.Chrome(executable_path='D:/selenium/chromedriver.exe')
super(JSPageMiddleware, self).__init__()
def process_request(self, request, spider):
# htmlResponse避免scrapy到downloader中重复下载。
# 一旦遇到htmlResponse,scrapy将不会在再向downloader发送请求,而是直接返回给spider。
# 注意,这里是同步请求
if spider.name == 'zhihu':
self.browser.get(request.url)
sleep(3)
print("访问{0}".format(request.url))
return HtmlResponse(url=self.browser.current_url, body=self.browser.page_source,
encoding='utf8', request=request)
3.激活Downloader中间件(Downloader Middlewares)
要启用Downloader中间件(Downloader Middlewares),可以将其加入到settings.py
中的DOWNLOADER_MIDDLEWARES设置中。 该设置是一个字典,键为中间件的路径,值为中间件的顺序(order)。
DOWNLOADER_MIDDLEWARES = {
'spider_pjt1.middlewares.JSPageMiddleware': 1,
}
4. 测试
# -*- coding: utf-8 -*-
# @Author : One Fine
# @File : main.py
from scrapy.cmdline import execute
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
# 调用execute()函数来执行命令,此方法传递一个数组作为参数
execute(["scrapy", "crawl", "zhihu"])
然而,我们发现通过Selenium启动的浏览器并没有关闭,我们来改写一下zhihu.py
文件。
5. 改写zhihu.py
文件和Downloader Middleware
这里涉及Scrapy信号量的知识,暂时不做解释。
# -*- coding: utf-8 -*-
# @Author : One Fine
# @File : zhihu.py
import scrapy
from selenium import webdriver
from scrapy.xlib.pydispatch import dispatcher
from scrapy import signals
class ZhihuSpider(scrapy.Spider):
name = 'zhihu'
allowed_domains = ['www.zhihu.com']
start_urls = ['http://www.zhihu.com/']
def __init__(self):
self.browser = webdriver.Chrome(executable_path='D:/selenium/chromedriver.exe')
super(ZhihuSpider, self).__init__()
# zhihu爬虫退出的时候关闭浏览器
dispatcher.connect(self.spider_closed, signals.spider_closed)
def spider_closed(self):
# 信号量的回调函数
print("spider closed")
self.browser.quit()
def parse(self, response):
yield []
相应的,Downloader Middleware有需要相应的修改:
from time import sleep
from scrapy.http import HtmlResponse
class JSPageMiddleware(object):
def process_request(self, request, spider):
if spider.name == 'zhihu':
spider.browser.get(request.url)
sleep(3)
return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source,
encoding='utf8', request=request)
至此, 我们已经将Selenium集成到Scrapy中。
参考:
爬虫(十五):scrapy中的settings详解 http://www.cnblogs.com/felixwang2/p/8798653.html
八.Scrapy 学习下Spider中间件Spider Middlewares https://blog.csdn.net/beyond_f/article/details/74626311
改写scrapy中的middlewares组件,建立user-agent池和IP代理池达到反爬的效果 https://blog.csdn.net/qq_41020281/article/details/79436643