• 爬虫2.5-scrapy框架-下载中间件


    scrapy框架-下载中间件

    middlewares.py中有两个类,一个是xxSpiderMiddleware类 一个是xxDownloaderMiddleware类,xx代表项目名,本次笔记主要记录DownloaderMiddleware类的一些知识点

    1. process_request(self, request, spider):

    这个方法会在请求之前执行,所以可以添加代理pi和随机请求头等

    1.1 参数:

    ​ reuqest:发送的请求

    ​ spider:发送请求的spider对象,即request是哪个爬虫对象发过来的。

    1.2 返回值:

    1)如果返回的是None:scrapy将把request对象交给下一个中间件

    2)如果返回的是response对象,则不会调用任何的process_request方法,而是将response对象直接返回给已激活的process_response()方法

    3)返回request对象,不会调用下一个中间件,而是根据返回的request对象返回数据

    4)抛出异常,调用process_exception方法。

    2. process_response(self, request, response, spider):

    2.1 参数:

    1)request:之前发送的request请求对象

    2)response:返回的数据对象

    3)spider:爬虫对象

    2.2 返回值:

    1)返回response对象,会将这个新的response对象传给其他中间件,最终传给爬虫

    2)返回request对象,下载器链被切断,返回的request会重新被下载器调度

    3)抛出异常,调用request中的errback方法,没有就抛出异常

    3. 设置请求头

    专业请求头网站 http://www.useragentstring.com/pages/useragentstring.php?type=Browser

    定义xxDownloaderMiddleware类,在写process_request()方法

    class xxDownloaderMiddleware(object):
        USER_AGENTS = [
            'xxxx',
            'xxxxx',
            'xxxx',
            'xxxxxx' # 请求头
            ]
    
    def process_request(self, request, spider):
    	user_agent = random.choice(self.USER_AGENTS)
        request.headers['user-agent'] = user_agent
    

    然后在settings.py中打开中间件设置

    DOWNLOADER_MIDDLEWARES = {
        'projectname.middlewares.xxDownloaderMiddleware': 543
    }
    

    4. ip代理池

    代理服务商:

    快递代理、芝麻代理、太阳代理、讯代理、蚂蚁代理

    当然是花钱买,免费的不好用

    新建一个类

    class XXXDownloaderMiddleware(object):
    	PROXIES = ['IP1','IP2','IP3']
        def process_request(self, request, spider):
            proxy = random.choice(self.PROXIES)
            request.meta('proxy') = proxy
    

    修改settings.py

    DOWNLOADER_MIDDLEWARES = {
        'project.middlewares.XXXDownloaderMiddleware':542 # 多个中间件的优先级自己设定,1为最高级
    }
    

    5. 一个略完善的代理思路

    开启两个下载中间件,一个请求头代理,一个ip代理,添加到settings中间

    ip代理中间件需要两个函数,

    1 process_request(self, request, spider)

    2 process_response(self, request, response, spider)

    函数1 获取代理ip、端口、过期时间可以调用代理网站给的api获取

    函数2 当ip被封,返回的是值是不一样的,所以可以return request对象 重新分配代理ip、端口

    伪代码:

    def process_request(self, request, spider):
    	if 'proxy' not in request.meta or 代理即将过期 or 代理被封:
    		更新代理
            更新代理被封标志
    	request.meta['proxy'] = 代理ip
    
    def process_response(self, request, response, spider):
    	if response.status != 200 or 验证码页面url特殊标志 in response.url:
    		代理被封标志
            更新代理
    		return request
        return response
    

    因为scrapy框架下各个请求是异步的,所以更新代理的函数需要进行一定的更改,因为每次将一个ip使用到被封才使用下一个ip,所以每个异步请求都应该使用同一个ip,过期或被封之后才更换

    def 更新代理:
    	加锁:
    	if 代理没有设置好 or 代理即将过期
    		请求代理ip
    	
    

    6. selenium+chromedriver中间件

    这个中间件相当于使用chromedriver访问页面,并将各类ajax数据传回给爬虫进行解析,而scrapy框架负责调度url和数据解析存储。

    当页面中ajax数据较多且复杂时,采用这种方式更方便。

    ~ meddlewares.py
    from selenium import webdriver
    from scrapy.http.response.html import HtmlResponse
    class SeleniumDownloaderMiddleware(object):
        def __init__(self):
            self.driver = webdriver.Chrome(executable_path=r'D:chromedriverchromedriver.exe')  # 创建driver
    
        def process_request(self, request, spider):
            self.driver.get(request.url)  # 打开不同的页面
            source = self.driver.page_source
            response = HtmlResponse(self.driver.current_url, body=source, request=request, encoding='utf-8')  # 传入的参数是按原本response对象需要的参数
            return response  # 必须返回response对象给爬虫
    

    最后在settings.py中开启这个中间件

    DOWNLOADER_MIDDLEWARES = {
       'boss.middlewares.SeleniumDownloaderMiddleware': 543,
    }
    

    作者:bitterz
    本文版权归作者和博客园所有,欢迎转载,转载请标明出处。
    如果您觉得本篇博文对您有所收获,请点击右下角的 [推荐],谢谢!
  • 相关阅读:
    快速排序算法C++实现[评注版]
    浮躁的程序员
    扬长避短使用Windbg和Visual Studio高效调试调试你的代码
    程序员,代码,理想,老男孩
    Windows Server 2008 R2 如何启动kernel dbg进行双机内核调试『续bcdedit 用法详解』
    Windows Server 2008 R2 如何启动kernel dbg进行双机内核调试『配置详解』
    忙着活或忙着死[转]
    SQL2005使用游标的实例(SBO中计算到期应收账款)
    C#编写的Windows计算器源代码
    请登录真正的BBS
  • 原文地址:https://www.cnblogs.com/bitterz/p/10202207.html
Copyright © 2020-2023  润新知