• 爬虫第七章 scrapy中间件 + 基于crawlSpider全站爬取网络数据


    scrapy中间件

    scrapy中间件分为两种:
        一种是:下载器和引擎之间的下载器中间件
            作用: 处于引擎和下载器之间,此中间件可以拦截整个工程中发起的请求和响应数据
        另一种是: 爬虫程序跟引擎之间的下载器中间件
    
    拦截请求干什么?
        代理ip : request.meta['proxy'] = 'http://ip:port'
        UA伪装 : request.headers['User-Agent'] = 'xxxxxx'
    
    拦截响应干什么?
        篡改响应数据 (基本上不会对响应数据进行修改)
        更换响应对象 (基本上就是用来更改代理ip)

    在scrapy中使用selenium
      在爬虫类中定义一个bro属性(selenium实例化的一个浏览器对象)
      在爬虫类中重写一个closed(self,spider),在该方法中关闭浏览器对象
      在中间件的process_response中通过spider参数爬取爬虫类中的bro属性
      在中间件中编写浏览器自动化操作获取页面源码数据
      将页面源码数据作为新响应对象的响应数据
      将新的响应对象返回


    基于crawlSpider的全站数据爬取

    crawlSpider和Spider之间的关联
        crawlSpider是Spider的一个子类
    创建一个基于crawlSpider的爬虫文件
        scrapy genspider -t crawl pcpro www.xxx.com

    实例代码:

    爬虫文件代码:

    import scrapy
    from scrapy.linkextractors import LinkExtractor
    from scrapy.spiders import CrawlSpider, Rule
    from sunShinePro.items import SunshineproItem,sunConetent
    
    # http://wz.sun0769.com/index.php/question/questionType?type=4&page=30
    class SunSpider(CrawlSpider):
        name = 'sun'
        # allowed_domains = ['www.xxx.com']
    
        start_urls = ['http://wz.sun0769.com/index.php/question/questionType?type=4&page=']
        #链接提取器
            #作用:根据 指定的规则(allow:正则) 提取页面源码中指定的连接
        link = LinkExtractor(allow=r'type=4&page=d+')
        link_detail = LinkExtractor(allow='question/d+/d+.shtml')
        rules = (
            #规则解析器:将连接提取器提取到的连接对应的页面源码数据 根据指定规则(callback) 进行数据解析
            Rule(link, callback='parse_item', follow=False),
            Rule(link_detail, callback='parse_detail'),
        )
        def parse_detail(self,response):
            content = response.xpath('/html/body/div[9]/table[2]//tr[1]/td/div[2]//text()').extract()
            content = ''.join(content)
    
            item = sunConetent()
            item['content'] = content
    
            yield item
    
        def parse_item(self, response):
            #注意:如果xpath定位的标签中存在tbody,则需要跳过tbody
            tr_list = response.xpath('//*[@id="morelist"]/div/table[2]//tr/td/table//tr')
            for tr in tr_list:
                title = tr.xpath('./td[2]/a[2]/text()').extract_first()
                status = tr.xpath('./td[3]/span/text()').extract_first()
                item = SunshineproItem()
                item['title'] = title
                item['status'] = status
    
                yield item

    pipelines.py中

    class SunshineproPipeline(object):
        def process_item(self, item, spider):
            if item.__class__.__name__ == 'SunshineproItem':
                print(item['title'], item['status'])
    
            else:
                print(item['content'])
            return item

    记得要在settings.py中打开管道

    spider和selenium一起使用

    实例代码:

    爬虫文件代码.py

    import scrapy
    
    from selenium import webdriver
    class WangyiSpider(scrapy.Spider):
        name = 'wangyi'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['https://news.163.com/world/']
    
        #实例化一个浏览器对象
        bro = webdriver.Chrome(executable_path=r'C:Usersold-boyDesktop爬虫day05爬虫chromedriver.exe')
        def parse(self, response):
            div_list = response.xpath('/html/body/div/div[3]/div[4]/div[1]/div/div/ul/li/div/div')
            for div in div_list:
                title = div.xpath('.//div[@class="news_title"]//a/text()').extract_first()
                detail_url = div.xpath('.//div[@class="news_title"]//a/@href').extract_first()
                yield scrapy.Request(detail_url,self.parse_detail)
                print(title,detail_url)
    
        def parse_detail(self,response):
            content = response.xpath('//*[@id="endText"]//text()').extract()
            content = ''.join(content)
            print(content)
        def closed(self,spider):
            self.bro.quit()

    middlewares.py中

    class WangyiproDownloaderMiddleware(object):
        #spider表示的就是爬虫类实例化的对象
        def process_response(self, request, response, spider):
            #将不符合需求的响应对象修改成符合需求的
            #body:响应数据
            #如何获取爬虫类中生成的浏览器对象呢?
            if request.url == 'https://news.163.com/world/':
                bro = spider.bro
                bro.get('https://news.163.com/world/')
                sleep(2)
                #滚动条滚动到最底部
                bro.excute_script('window.scrollTo(0,document.body.scrollHeight)')
                sleep(1)
                bro.excute_script('window.scrollTo(0,document.body.scrollHeight)')
                sleep(1)
                bro.excute_script('window.scrollTo(0,document.body.scrollHeight)')
                sleep(1)
                page_text = bro.page_source
    
                new_response = HtmlResponse(url=bro.current_url,body=page_text,encoding='utf-8',request=request)
    
                return new_response
            else:
                return response #一定要返回原始数据,否则只能获取到一部分内容

    在settings.py中我们要配置以下参数:

    #下载器和引擎之间的中间件
    DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMiddleware': 543, }
  • 相关阅读:
    20145236 《信息安全系统设计基础》第11周学习总结
    20145308 《信息安全系统设计基础》课程总结
    20145308 《信息安全系统设计基础》第14周学习总结
    20145308 《信息安全系统设计基础》第13周学习总结
    20145308刘昊阳 20145302张薇《信息安全系统设计基础》实验五:网络通信 实验报告
    20145308 《信息安全系统设计基础》第12周学习总结
    GDB调试汇编堆栈
    20145302张薇 20145308刘昊阳 《信息安全系统设计基础》实验四:外设驱动设备设计 实验报告
    20145308 《信息安全系统设计基础》第11周学习总结
    20145302张薇 20145308刘昊阳 《信息安全系统设计基础》实验三 实时系统的移植 实验报告
  • 原文地址:https://www.cnblogs.com/zty1304368100/p/11055203.html
Copyright © 2020-2023  润新知