zoukankan      html  css  js  c++  java
  • scrapy中间件之下载中间件使用(网易新闻爬取)

    scrapy项目中的middlewarse.py中间件  

    爬虫中间件:目前先不介绍

    下载中间件(需要在settings.py中开启) 

                    

    (1)请求处理函数:process_request(self, request, spider)
      可以针对url请求指定UA伪装、配置代理等功能(UA伪装可以在settings.py中进行全局配置,代理配置更倾向于在异常处理函数,大部分异常都是因为ip的问题)  
    1   def process_request(self, request, spider):
    2         #UA伪装
    3         # request.headers['User-Agent']=random.choice(UA_list)
    4         
    5         #ip代理配置(一般更多的放在process_exception异常处理函数中)
    6         # request.meta['proxy']='http[s]://ip:port'
    7         return None
    process_request
    (2)响应处理函数:process_response(self, request, response, spider)
      对于一些网页请求,立即相应的数据可能不完全,页面部分内容是通过触发滚轮或者下拉操作才会动态加载的数据,因此获取的到数据并不是完整的,需要对响应对象进行篡改(比如通过selenium模拟浏览器操作获取到完整数据)后返回。
      
    (3)异常处理函数:process_exception(self, request, exception, spider)
      对于请求异常处理,一般可以更换ip设置代理操作
    1  def process_exception(self, request, exception, spider):
    2         #对请求异常进行修正
    3         #更换代理(一定要 return request将请求返回以便再次发起)
    4         # request.meta['proxy']='http[s]://ip:port'
    5         # return request
    6         pass
    process_exception

    网易新闻爬取案例:

      分析页面可以获知不同板块内容都是页面下拉动态加载的:国内、国际、军事、航空、无人机这几个板块内容都是标题都是在div中的一个a标签中,因此统一来进行爬取解析!

       1.新建爬虫项目  

    scrapy startproject firstPro
    cd firstPro
    scrapy genspider middlewareTest www.xxx.com  

      2.编写爬虫文件middlewareTest.py

     1 # -*- coding: utf-8 -*-
     2 import scrapy
     3 from firstPro.items import FirstproItem
     4 from selenium import webdriver
     5 
     6 
     7 class MiddlewaretestSpider(scrapy.Spider):
     8     name = 'middlewareTest'
     9     # allowed_domains = ['www.xxx.com']
    10     start_urls = ['https://news.163.com/']
    11     plate_urls=[]#存放板块的url,以便在下载中间件次改请求获取完整标题数据
    12     def __init__(self):
    13         self.bro=webdriver.Chrome(executable_path=r'E:Python项目爬虫day110_20190809(全站爬取、分布式爬虫)firstProfirstProspiderschromedriver.exe')#初始化浏览器实例
    14     def parse(self, response):
    15         #解析首页标题板块
    16         li_list=response.xpath('//div[@class="ns_area list"]/ul/li')
    17         print(len(li_list))
    18         #确定爬取的板块
    19         index_list=[4,5,7,8,9]
    20         for index in index_list:
    21             item=FirstproItem()
    22             plate=li_list[index-1].xpath('./a/text()').extract_first()
    23             url=li_list[index-1].xpath('./a/@href').extract_first()
    24             self.plate_urls.append(url)
    25             item['plate']=plate
    26             # 对每个板块进行发起请求,获取标题信息
    27             yield scrapy.Request(url,callback=self.parse_title,meta={"item":item})
    28             break
    29     #对每个板块的新闻标题进行解析,但是新闻标题都是动态加载的,因此直接的响应对象不完整,需要通过下载中间件对新闻板块标题获取进行处理
    30     #解决思路:为获取板块完整标题内容,需要模拟浏览器下拉操作,结合使用selenuim在下载中间件进行操作
    31     def parse_title(self, response):
    32         item=response.meta['item']
    33         #解析每个板块中的新闻标题
    34         div_list=response.xpath('//div[@class="ndi_main"]/div')
    35         for div in div_list:
    36             title=div.xpath('./div/div[1]/h3/a/text()').extract_first()
    37             url=div.xpath('./div/div[1]/h3/a/@href').extract_first()
    38             item["title"]=title
    39             #对每个标题详情发起请求
    40             yield scrapy.Request(url,callback=self.parse_detail,meta={"item":item})
    41 
    42     def parse_detail(self,response):
    43         item = response.meta['item']
    44         #解析每个标题对应的详细新闻内容
    45         content="".join(response.xpath('//*[@id="endText"]//text()').extract())
    46         item["content"]=content
    47         yield item
    48 
    49     # 程序全部结束的时候被调用
    50     def closed(self, spider):
    51         print('结束爬虫!!!')
    52         self.bro.quit()
    爬虫脚本middlewareTest.py

      3.定义items.py字段属性

     1 import scrapy
     2 
     3 class FirstproItem(scrapy.Item):
     4     # define the fields for your item here like:
     5     # name = scrapy.Field()
     6     #新闻板块
     7     plate=scrapy.Field()
     8     #新闻标题
     9     title=scrapy.Field()
    10     #新闻详情
    11     content=scrapy.Field()
    12     pass
    items.py

      4.管道pipelines.py持久化

     1 import redis
     2 class FirstproPipeline(object):
     3     #持久化存储在redis数据库中
     4     conn=None
     5     # def open_spider(self,spider):
     6     #     self.conn=redis.Redis(host="127.0.0.1",port=6379)
     7 
     8     def process_item(self, item, spider):
     9         # self.conn.lpush('wangyi',dict(item))
    10         print(item)
    11         return item
    pipelines.py

      5.settings.py配置

     1 #UA伪装
     2 USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
     3 
     4 #robots协议
     5 ROBOTSTXT_OBEY = False
     6 
     7 #输出日志等级
     8 LOG_LEVEL="ERROR"
     9 
    10 #打开下载中间件
    11 DOWNLOADER_MIDDLEWARES = {
    12    'firstPro.middlewares.FirstproDownloaderMiddleware': 543,
    13 }
    14 
    15 #打开管道
    16 ITEM_PIPELINES = {
    17    'firstPro.pipelines.FirstproPipeline': 300,
    18 }
  • 相关阅读:
    78. Subsets
    93. Restore IP Addresses
    71. Simplify Path
    82. Remove Duplicates from Sorted List II
    95. Unique Binary Search Trees II
    96. Unique Binary Search Trees
    312. Burst Balloons
    程序员社交平台
    APP Store开发指南
    iOS框架搭建(MVC,自定义TabBar)--微博搭建为例
  • 原文地址:https://www.cnblogs.com/open-yang/p/11341127.html
Copyright © 2011-2022 走看看