爬虫之scrapy+seleniumm

        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都可以),并打开。

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值