scrapy是一款功能非常强大的爬虫框架,但是有些网站反爬力度之大令人瞠目结舌,靠单纯的技术很难爬取,这时候scrapy加上selenium也是种不错的选择。
selenium在scrapy中扮演的角色是下载器,它需要在请求发过来是判断一下这个请求是否需要用selenium解决,如果需要,就用selenium,不需要的话直接给原来的下载器进行请求。
那么问题来了,selemium放在哪里比较好呢,答案就是中间件啦,下载器中间件中的spider_request中当请求过来的时候是需要selenium就返回response对象,不需要就返回None让他继续执行,有一点需要注意,有很多中间件在selinium中默认是打开的,selenium可是不需要这玩意的,已知默认中间件的权重最大是100,我们需要把selenium中间件设置成<100的,这样就会优先执行了。接下来说一下流程:
首先需要在middleware.py的同级目录下新建一个request.py,在这个python文件中新建一个SeleniumRequest类并且继承scrapy中的request类,因为在一个scrapy中不可能只有一个爬虫,肯定有不需要selenium发送请求的,所以需要用这个来区分,需要selenium的用SeleniumReqest,不需要的用scrapy中的request。
然后对于需要用到selenium的爬虫文件,重写start_request方法,让他调用SelemiumRequest。
接下来需要回到中间件了,在spider_requset中先判断请求是否需要selenium不需要就return None,需要就来时selemium操作,
最后需要把selenium的返回值封装成request对象进行返回。
接下来开始操作:
新建request.py
继承Request
from scrapy import Request
#为什么什么都不需要做啊
#因为已经继承了Request了,Request中的东西够用了。
#创建这个只是为了区分SeleniumRequest和Request
class SeleniumRequest(Request):
pass
重写start_request
def start_requests(self) -> Iterable[Request]:
yield SeleniumRequest(url=self.start_urls[0], callback=self.parse())
创建selenium中间件并返回响应对象
class SelemiumDownloaderMiddleware:
# Not all methods need to be defined. If a method is not defined,
# scrapy acts as if the downloader middleware does not modify the
# passed objects.
@classmethod
def from_crawler(cls, crawler):
# This method is used by Scrapy to create your spiders.
s = cls()
crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)
#新建closed
crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)
return s
def process_request(self, request, spider):
# 判断是否为SesniumRequest请求
if isinstance(request, SeleniumRequest):
self.driver.get(request.url)
page_source = driver.page_source
#封装response对象
resp = HtmlResponse(url=request.url, status = 200,body=page_source, encoding='utf-8')
return resp
else:
#不是就去下一个中间件
return None
def spider_opened(self, spider):
opt = webdriver.ChromeOptions()
# 禁止显示“Chrome正在受到自动测试软件的控制”等信息提示栏
opt.add_argument('--disable-infobars')
# 排除 enable-automation 开关,这可以帮助用户隐藏自动化测试的痕迹,从而降低被识别为自动化程序的风险
opt.add_experimental_option("excludeSwitches", ["enable-automation"])
# 禁用 Chrome 浏览器中的自动化扩展程序(Automation Extension),这有助于减少浏览器检测到自动化测试的可能性。
opt.add_experimental_option('useAutomationExtension', False)
self.driver = webdriver.Chrome(service=service,options=opt)
with open('./hide.js', 'r', encoding='utf-8') as f:
self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": f.read()})
def spider_closed(self, spider):
self.driver.close()
最后,别忘了把SelemiumDownloaderMiddleware权重设置为80(小于100都可以),并打开。
本文转载自: https://blog.csdn.net/weixin_53984419/article/details/137084045
版权归原作者 某得感情 所有, 如有侵权,请联系我们删除。
版权归原作者 某得感情 所有, 如有侵权,请联系我们删除。