• scrapy中selenium的应用


    引入

    在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值。但是通过观察我们会发现,通过浏览器进行url请求发送则会加载出对应的动态加载出的数据。那么如果我们想要在scrapy也获取动态加载出的数据,则必须使用selenium创建浏览器对象,然后通过该浏览器对象进行请求发送,获取动态加载的数据值。

    案例:爬取网易新闻的国内板块下的新闻数据

    1.案例分析:

        - 需求:爬取网易新闻的国内板块下的新闻数据,新闻主题和详情页url

        - 需求分析:当点击国内超链进入国内对应的页面时,会发现当前页面展示的新闻数据是被动态加载出来的,如果直接通过程序对url进行请求,是获取不到动态加载出的新闻数据的。则就需要我们使用selenium实例化一个浏览器对象,在该对象中进行url的请求,获取动态加载的新闻数据。

    2.selenium在scrapy中使用的原理分析:

    当引擎将国内板块url对应的请求提交给下载器后,下载器进行网页数据的下载,然后将下载到的页面数据,封装到response中,提交给引擎,引擎将response在转交给Spiders。Spiders接受到的response对象中存储的页面数据里是没有动态加载的新闻数据的。要想获取动态加载的新闻数据,则需要在下载中间件中对下载器提交给引擎的response响应对象进行拦截,对其内部存储的页面数据进行篡改,修改成携带了动态加载出的新闻数据,然后将被篡改的response对象最终交给Spiders进行解析操作。

    3.selenium在scrapy中的使用流程:

    • 重写爬虫文件的构造方法,在该方法中使用selenium实例化一个浏览器对象(因为浏览器对象只需要被实例化一次)
    • 重写爬虫文件的closed(self,spider)方法,在其内部关闭浏览器对象。该方法是在爬虫结束时被调用
    • 重写下载中间件的process_response方法,让该方法对响应对象进行拦截,并篡改response中存储的页面数据
    • 在配置文件中开启下载中间件

    4.代码

    爬虫文件:

    # -*- coding: utf-8 -*-
    import scrapy
    from selenium import webdriver
    
    
    class WangyiSpider(scrapy.Spider):
        name = 'wangyi'
        # allowed_domains = ['www.wangyi.com']
        start_urls = ['http://news.163.com/domestic/']
        def __init__(self):
            self.bro = webdriver.Chrome(executable_path=r'D:爬虫+数据分析	oolschromedriver.exe')
    
        def parse(self, response):
            # 解析数据
            div_list = response.xpath('//div[@class="ndi_main"]/div')
            for div in div_list:
                title = div.xpath('./div/div[1]/h3/a/text()').extract_first()
                # 详情页的url
                detail_url = div.xpath('./div/div[1]/h3/a/@href').extract_first()
                print(title,detail_url)
    
        def closed(self, spider):
            self.bro.quit()

     中间件文件:

    from scrapy import signals
    from time import sleep
    from scrapy.http import HtmlResponse
    
    
    # 下载中间件
    class WangyiproDownloaderMiddleware(object):
        # 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)
            return s
    
        def process_request(self, request, spider):
            return None
    
        # 拦截所有的响应对象
        def process_response(self, request, response, spider):
            # 参数spider表示的就是爬虫类的一个对象
            # 使用一个满足需求的新的响应对象替换原有的
            bro = spider.bro  # 浏览器对象
            url = spider.start_urls[0]
            bro.get(url)
            # 滚动滚轮加载动态数据
            bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
            sleep(2)
            bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
            sleep(2)
            bro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
            sleep(2)
            a_tag = bro.find_elements_by_class_name('load_more_btn')[0]
            a_tag.click()  # 点击加载更多
            page_text = bro.page_source
            # 实例化一个新的响应对象
            response = HtmlResponse(url=bro.current_url, body=page_text, encoding='utf-8', request=request)
            return response
    
        def process_exception(self, request, exception, spider):
            # Called when a download handler or a process_request()
            # (from other downloader middleware) raises an exception.
    
            # Must either:
            # - return None: continue processing this exception
            # - return a Response object: stops process_exception() chain
            # - return a Request object: stops process_exception() chain
            pass
    
        def spider_opened(self, spider):
            spider.logger.info('Spider opened: %s' % spider.name)

    配置文件中开启下载中间件

  • 相关阅读:
    得到内网可用的SqlServer 及某数据库下的表及其他的架构
    VS2005 XML注释生成XML文档文件
    华表 单元格公式设定与计算
    自定义控件开发示例二
    自定义控件的 Enum类和Color类 属性的公开设定
    入门者初试 Cell(华表)结合C#的应用
    VS2005 + VSS6.0 简单应用示例
    SQL2000联机丛书:使用和维护数据仓库
    VS2005 通过SMO(SQL Management Objects) 管理 数据库的作业 警报 备份 等任务
    SQL2000联机丛书:基本 MDX
  • 原文地址:https://www.cnblogs.com/zwq-/p/10596798.html
Copyright © 2020-2023  润新知