用scrapy写爬虫(八)中间件的应用

网易新闻爬取

(1)请求处理函数:process_request(self, request, spider)
  可以针对url请求指定UA伪装、配置代理等功能(UA伪装可以在settings.py中进行全局配置,代理配置更倾向于在异常处理函数,大部分异常都是因为ip的问题)
def process_request(self, request, spider):
        #UA伪装
        # request.headers['User-Agent']=random.choice(UA_list)
        
        #ip代理配置(一般更多的放在process_exception异常处理函数中)
        # request.meta['proxy']='http[s]://ip:port'
        return None

(2)响应处理函数:process_response(self, request, response, spider)
  对于一些网页请求,立即相应的数据可能不完全,页面部分内容是通过触发滚轮或者下拉操作才会动态加载的数据,因此获取的到数据并不是完整的,需要对响应对象进行篡改(比如通过selenium模拟浏览器操作获取到完整数据)后返回。
(3)异常处理函数:process_exception(self, request, exception, spider)
  对于请求异常处理,一般可以更换ip设置代理操作
def process_exception(self, request, exception, spider):
        #对请求异常进行修正
        #更换代理(一定要 return request将请求返回以便再次发起)
        # request.meta['proxy']='http[s]://ip:port'
        # return request
        pass

网易新闻爬取案例:

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

 1.新建爬虫项目  

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

 2.编写爬虫文件

# -*- coding: utf-8 -*-
import scrapy
from firstPro.items import FirstproItem
from selenium import webdriver


class MiddlewaretestSpider(scrapy.Spider):
    name = 'middlewareTest'
    # allowed_domains = ['www.xxx.com']
    start_urls = ['https://news.163.com/']
    plate_urls=[]#存放板块的url,以便在下载中间件次改请求获取完整标题数据
    def __init__(self):
        self.bro=webdriver.Chrome(executable_path=r'E:\Python项目\爬虫\day110_20190809(全站爬取、分布式爬虫)\firstPro\firstPro\spiders\chromedriver.exe')#初始化浏览器实例
    def parse(self, response):
        #解析首页标题板块
        li_list=response.xpath('//div[@class="ns_area list"]/ul/li')
        print(len(li_list))
        #确定爬取的板块
        index_list=[4,5,7,8,9]
        for index in index_list:
            item=FirstproItem()
            plate=li_list[index-1].xpath('./a/text()').extract_first()
            url=li_list[index-1].xpath('./a/@href').extract_first()
            self.plate_urls.append(url)
            item['plate']=plate
            # 对每个板块进行发起请求,获取标题信息
            yield scrapy.Request(url,callback=self.parse_title,meta={"item":item})
            break
    #对每个板块的新闻标题进行解析,但是新闻标题都是动态加载的,因此直接的响应对象不完整,需要通过下载中间件对新闻板块标题获取进行处理
    #解决思路:为获取板块完整标题内容,需要模拟浏览器下拉操作,结合使用selenuim在下载中间件进行操作
    def parse_title(self, response):
        item=response.meta['item']
        #解析每个板块中的新闻标题
        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=div.xpath('./div/div[1]/h3/a/@href').extract_first()
            item["title"]=title
            #对每个标题详情发起请求
            yield scrapy.Request(url,callback=self.parse_detail,meta={"item":item})

    def parse_detail(self,response):
        item = response.meta['item']
        #解析每个标题对应的详细新闻内容
        content="".join(response.xpath('//*[@id="endText"]//text()').extract())
        item["content"]=content
        yield item

    # 程序全部结束的时候被调用
    def closed(self, spider):
        print('结束爬虫!!!')
        self.bro.quit()

3.编写item.py字段属性

import scrapy

class FirstproItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    #新闻板块
    plate=scrapy.Field()
    #新闻标题
    title=scrapy.Field()
    #新闻详情
    content=scrapy.Field()
    pass

4.settings.py 配置

#UA伪装
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"

#robots协议
ROBOTSTXT_OBEY = False

#输出日志等级
LOG_LEVEL="ERROR"

#打开下载中间件
DOWNLOADER_MIDDLEWARES = {
   'firstPro.middlewares.FirstproDownloaderMiddleware': 543,
}

#打开管道
ITEM_PIPELINES = {
   'firstPro.pipelines.FirstproPipeline': 300,
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值