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(全站爬取、分布式爬虫)\firstPro\firstPro\spiders\chromedriver.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 }

 

posted @ 2019-08-12 19:17  笑得好美  阅读(275)  评论(0编辑  收藏  举报