Python爬虫5.10 — scrapy框架Download Middlewares[下载器中间件]的使用

编程入门 行业动态 更新时间:2024-10-23 10:25:38

Python<a href=https://www.elefans.com/category/jswz/34/1770264.html style=爬虫5.10 — scrapy框架Download Middlewares[下载器中间件]的使用"/>

Python爬虫5.10 — scrapy框架Download Middlewares[下载器中间件]的使用

Python爬虫5.10 — scrapy框架Download Middlewares[下载器中间件]的使用

    • 综述
    • Download Middlewares(下载器中间件)
      • process_request(self, request, spider)
      • process_response(self, request, response, spider)
      • 中间件其他方法
    • 实例说明
      • 随机请求头中间件
      • IP代理池中间件
        • 开放代理开发
        • 独享代理开发
    • 其他博文链接

综述

本系列文档用于对Python爬虫技术的学习进行简单的教程讲解,巩固自己技术知识的同时,万一一不小心又正好对你有用那就更好了。
Python 版本是3.7.4

本篇文章主要Scrapy框架的Download Middlewares(下载器中间件)模块的使用,下载器中间的作用主要用于进行反爬虫。主要内容包含:

  1. 如何设置请求头
  2. 设置ip代理

Download Middlewares(下载器中间件)

下载器中间件是引擎和下载器之间通信的中间件。在这个中间件中我们可以设置代理、更换请求头信息等来达到反反爬虫的目的。要写下载器中间,可以在下载器中实现两个方法。一个是process_request(self, request, spider),这个方法是在请求发送之前会执行,还有一个是process_response(self, request, response, spider),这个方法是数据下载到引擎之前执行。

process_request(self, request, spider)

这个方法是在下载器发送请求之前会执行的,一般可以在这个里卖弄设置随机代理,随机请求头等。

  1. 参数
    • request : 发送请求的request对象。
    • spider : 发送请求的spider对象。
  2. 返回值
    • 返回Node:如果返回None,Scrapy将继续吃力该request,执行中间件中的相应的方法,知道合适的下载器处理函数被调用。
    • 返回Response对象:Scrapy将不会调用其他的process_request方法,将直接返回这个response对象。已经激活的中间件的process_response()方法则会在每个response返回时被调用。
    • 返回Request对象:不再使用之前的request对象去下载数据,而是根据限制返回request对象返回数据。
    • 如果这个方法中抛出了异常,则会调用process_exception方法。

process_response(self, request, response, spider)

这个方法是下载器下载的数据到引擎中间会执行的方法。

  1. 参数
    • request:request对象。
    • response:被处理的response对象。
    • spider:spider对象.
  2. 返回值
    • 返回Response对象:会将这个新的response对象传给其他中间件,最终传给爬虫。
    • 返回Request对象:下载器链被切断,返回的resquest会重新被下载器调度下载。
    • 如果这个方法中抛出了异常,那么将会调用request的errorback方法,如果没有指定这个方法,那么会抛出一个异常。

中间件其他方法

  1. from_crawler(cls, crawler):如果存在该函数,from_crawler会被调用使用crawler来创建中间器对象,必须返回一个中间器对象,通过这种方式,可以访问到crawler的所有核心部件,如settings、signals等;
  2. process_exception(self, request, exception, spider):当process_response()和process_request()抛出异常时会被调用,应该返回以下对象:None/Response对象/Request对象;
  3. spider_opened(self, spider):当spider开始爬取时发送该信号。该信号一般用来分配spider的资源,不过其也能做任何事。

实例说明

随机请求头中间件

爬虫在频繁访问一个页面的时候,这个请求头如果一直保持一致,那么很容易被服务器发现,从而简直掉这个请求头的访问。因此我们要在访问这个页面之前随机更改请求头,这样才可以避免爬虫被抓。随机更改请求头,可以在下载中间件中实现,在请求发送给服务器之前,随机的选中一个请求头,这样就可以避免总是用一个请求头了。具体开发步骤如下:

  1. 使用Scrapy命令创建项目、创建爬虫(此步不做代码展示说明);
  2. 开发修改spider模块文件代码如下:
    import scrapyclass HttpbinSpider(scrapy.Spider):name = 'httpbin'allowed_domains = ['httpbin']start_urls = ['']def parse(self, response):print(response.text)yield scrapy.Request(self.start_urls[0], dont_filter=True)
    
  3. 开发下载器中间件middlewares.py代码如下:
    import randomclass UseragentDemoDownloaderMiddleware(object):USER_AGENTS = ['Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36','Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML like Gecko) Chrome/44.0.2403.155 Safari/537.36','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36','Mozilla/5.0 (X11; Linux i686; rv:64.0) Gecko/20100101 Firefox/64.0','Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0','Mozilla/5.0 (X11; Linux i586; rv:63.0) Gecko/20100101 Firefox/63.0','Mozilla/5.0 (Windows NT 6.2; WOW64; rv:63.0) Gecko/20100101 Firefox/63.0',]def process_request(self, request, spider):user_agent = random.choice(self.USER_AGENTS)request.headers['User-Agent'] = user_agent
    
  4. 修改setting.py配置文件,开启下载器中间件,代码如下:
    DOWNLOADER_MIDDLEWARES = {'useragent_demo.middlewares.UseragentDemoDownloaderMiddleware': 543,
    }
    

运行即可看到请求头切换打印效果。

Scrapy框架为我们提供了一个请求头代理中间件类UserAgentMiddleware:

scrapy.downloadermiddlewares.useragent.UserAgentMiddleware

通过配置项USER_AGENT设置用户代理:

settings.py
#...
#UserAgentMiddleware默认打开
USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'
#...

IP代理池中间件

关于代理IP相关的我们在前面的基础教程文章中已经讲过很多遍,在这里就不再进行说明了。Scrapy框架提供了一个代理代理服务器中间件类HttpProxyMiddleware

scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware

用以设置代理服务器,通过设定request.meta['proxy']来设置代理,会从环境变量http_proxyhttps_proxyno_proxy依次获取。设置代理我们有两种方式,一种设置是开放代理(开放代理就是有ip和port,不用用户名和密码就可使用),另外一种是独享代理,需要用户名和密码才能访问。

我们以的返回进行样理测试样例开发。

开放代理开发

开发中间件类代码如下:

import randomclass IpProxyDownloaderMiddleware(object):PROXIES = ['202.109.157.47:9000','115.28.148.192:8118',]def process_request(self, request, spider):proxy = random.choice(self.PROXIES)print(proxy)request.meta['proxy'] = "http://" + proxy

开发spider爬虫模块代码如下:

import scrapyclass IpproxySpider(scrapy.Spider):name = 'ipproxy'allowed_domains = ['httpbin']start_urls = ['']def parse(self, response):print(response.text)yield scrapy.Request(self.start_urls[0], dont_filter=True)

setting.py中设置中间件如下:

DOWNLOADER_MIDDLEWARES = {# 'useragent_demo.middlewares.UseragentDemoDownloaderMiddleware': 543,'useragent_demo.middlewares.IpProxyDownloaderMiddleware': 544,
}

运行查看结构即可,有的部分童鞋会有可能遇到这样的错误:

[scrapy.core.scraper] ERROR: Error downloading <GET ;
Traceback (most recent call last):File "D:\Python\Python37\lib\site-packages\twisted\internet\defer.py", line 1416, in _inlineCallbacksresult = result.throwExceptionIntoGenerator(g)File "D:\Python\Python37\lib\site-packages\twisted\python\failure.py", line 512, in throwExceptionIntoGeneratorreturn g.throw(self.type, self.value, self.tb)File "D:\Python\Python37\lib\site-packages\scrapy\core\downloader\middleware.py", line 44, in process_requestdefer.returnValue((yield download_func(request=request, spider=spider)))File "D:\Python\Python37\lib\site-packages\scrapy\utils\defer.py", line 45, in mustbe_deferredresult = f(*args, **kw)File "D:\Python\Python37\lib\site-packages\scrapy\core\downloader\handlers\__init__.py", line 71, in download_requestreturn handler.download_request(request, spider)File "D:\Python\Python37\lib\site-packages\scrapy\core\downloader\handlers\http11.py", line 68, in download_requestreturn agent.download_request(request)File "D:\Python\Python37\lib\site-packages\scrapy\core\downloader\handlers\http11.py", line 332, in download_requestmethod, to_bytes(url, encoding='ascii'), headers, bodyproducer)File "D:\Python\Python37\lib\site-packages\scrapy\core\downloader\handlers\http11.py", line 253, in requestproxyEndpoint = self._getEndpoint(self._proxyURI)File "D:\Python\Python37\lib\site-packages\twisted\web\client.py", line 1715, in _getEndpointreturn self._endpointFactory.endpointForURI(uri)File "D:\Python\Python37\lib\site-packages\twisted\web\client.py", line 1593, in endpointForURIraise SchemeNotSupported("Unsupported scheme: %r" % (uri.scheme,))
twisted.web.error.SchemeNotSupported: Unsupported scheme: b''

出现这种错误的原因是因为在中间件中进行设置IP代理池的时候没有添加传输协议,在上面的下载中间件中设置代理时,需要添加协议名称,“http://”或者“https://”。即可将此问题解决。

独享代理开发

将上例中间件代码修改为如下即可:

import random
import base64class IpProxyDownloaderMiddleware(object):def process_request(self, request, spider):# 你的独享代理ip和端口号proxy = 'ip:port'user_password = 'username:password'request.meta['proxy'] = "http://" + proxy# bytesb64_user_password = base64.b64encode(user_password.encode('utf-8'))request.headers['Proxy-Authorization'] = 'Basic ' + b64_user_password.decode('utf-8')

其他博文链接

  • Python爬虫1.1 — urllib基础用法教程
  • Python爬虫1.2 — urllib高级用法教程
  • Python爬虫1.3 — requests基础用法教程
  • Python爬虫1.4 — requests高级用法教程
  • Python爬虫2.1 — BeautifulSoup用法教程
  • Python爬虫2.2 — xpath用法教程
  • Python爬虫3.1 — json用法教程
  • Python爬虫3.2 — csv用法教程
  • Python爬虫3.3 — txt用法教程
  • Python爬虫4.1 — threading(多线程)用法教程
  • Python爬虫4.2 — ajax(动态网页数据抓取)用法教程
  • Python爬虫4.3 — selenium基础用法教程
  • Python爬虫4.4 — selenium高级用法教程
  • Python爬虫4.5 — tesseract(图片验证码识别)用法教程
  • Python爬虫5.1 — scrapy框架简单入门
  • Python爬虫5.2 — scrapy框架pipeline模块的使用
  • Python爬虫5.3 — scrapy框架spider[Request和Response]模块的使用
  • Python爬虫5.4 — scrapy框架items模块的使用
  • Python爬虫5.5 — scrapy框架logging模块的使用
  • Python爬虫5.6 — scrapy框架setting模块的使用
  • Python爬虫5.7 — scrapy框架Shell命令的使用
  • Python爬虫5.8 — scrapy框架CrawlSpider模块的使用
  • Python爬虫5.9 — scrapy框架下载文件和图片

更多推荐

Python爬虫5.10 — scrapy框架Download Middlewares[下载器中间件]的使用

本文发布于:2024-02-24 21:46:02,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1696760.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:爬虫   中间件   框架   下载器   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!