Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能示例


Posted in Python onAugust 04, 2018

本文实例讲述了Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能。分享给大家供大家参考,具体如下:

一、背景:

小编在爬虫的时候肯定会遇到被封杀的情况,昨天爬了一个网站,刚开始是可以了,在settings的设置DEFAULT_REQUEST_HEADERS伪装自己是chrome浏览器,刚开始是可以的,紧接着就被对方服务器封杀了。

代理:

代理,代理,一直觉得爬去网页把爬去速度放慢一点就能基本避免被封杀,虽然可以使用selenium,但是这个坎必须要过,scrapy的代理其实设置起来很简单。

注意,request.meta['proxy']=代理ip的API

middlewares.py

class HttpbinProxyMiddleware(object):
  def process_request(self, request, spider):
    pro_addr = requests.get('http://127.0.0.1:5000/get').text
    request.meta['proxy'] = 'http://' + pro_addr
    #request.meta['proxy'] = 'http://' + proxy_ip

设置启动上面我们写的这个代理

settings.py

DOWNLOADER_MIDDLEWARES = {
  'httpbin.middlewares.HttpbinProxyMiddleware': 543,
}

spiders

httpbin_test.py

import scrapy
class HttpbinTestSpider(scrapy.Spider):
  name = "httpbin_test"
  allowed_domains = ["httpbin.ort/get"]
  start_urls = ['http://httpbin.org/get']
  def parse(self, response):
    print(response.text)

origin的值其实就是本地的公网地址,但是因为我们用了代理,这里的ip是美国的一个ip

Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能示例

Python爬虫框架scrapy实现downloader_middleware设置proxy代理功能示例

二、那么问题来了,现在有这么一个场景,如上所述的话,我每个请求都会使用代理池里面的代理IP地址,但是有些操作是不需要代理IP地址的,那么怎么才能让它请求超时的时候,再使用代理池的IP地址进行重新请求呢?

spider:

1、我们都知道scrapy的基本请求步骤是,首先执行父类里面(scrapy.Spider)里面的start_requests方法,

2、然后start_requests方法也是取拿我们设置的start_urls变量里面的url地址

3、最后才执行make_requests_from_url方法,并只传入一个url变量

那么,我们就可以重写make_requests_from_url方法,从而直接调用scrapy.Request()方法,我们简单的了解一下里面的几个参数:

1、url=url,其实就是最后start_requests()方法里面拿到的url地址

2、meta这里我们只设置了一个参数,download_timeout:10,作用就是当第一次发起请求的时候,等待10秒钟,如果没有请求成功的话,就会直接执行download_middleware里面的方法,我们下面介绍。

3、callback回调函数,其实就是本次的本次所有操作完成后执行的操作,注意,这里可不是说执行完上面所有操作后,再执行这个操作,比如说请求了一个url,并且成功了,下面就会执行这个方法。

4、dont_filter=False,这个很重要,有人说过不加的话默认就是False,但是亲测必须得加,作用就是scrapy默认有去重的方法,等于False的话就意味着不参加scrapy的去重操作。亲测,请求一个页面,拿到第一个页面后,抓取想要的操作后,第二页就不行了,只有加上它才可以。

import scrapy
class HttpbinTestSpider(scrapy.Spider):
  name = "httpbin_test"
  allowed_domains = ["httpbin.ort/get"]
  start_urls = ['http://httpbin.org/get']
  def make_requests_from_url(self,url):
    self.logger.debug('Try first time')
    return scrapy.Request(url=url,meta={'download_timeout':10},callback=self.parse,dont_filter=False)
  def parse(self, response):
    print(response.text)

middlewares.py

下面就是上面请求10秒后超时会执行的操作process_exception方法,心细的同学会发现,我们在spider文件里面输出log的时候,是直接输出的,那是因为scrapy早都在父类里面给你定义好了,直接应用就行,但是在middlewares里面需要自己定义一个类变量定义,才能使用引用。

class HttpbinProxyMiddleware(object):
  logger = logging.getLogger(__name__)
  # def process_request(self, request, spider):
  #   # pro_addr = requests.get('http://127.0.0.1:5000/get').text
  #   # request.meta['proxy'] = 'http://' + pro_addr
  #   pass
  #
  # def process_response(self, request, response, spider):
  #   # 可以拿到下载完的response内容,然后对下载完的内容进行修改(修改文本的编码格式等操作)
  #   pass
  def process_exception(self, request, response, spider):
    self.logger.debug('Try Exception time')
    self.logger.debug('Try second time')
    proxy_addr = requests.get('http://127.0.0.1:5000/get').text
    self.logger.debug(proxy_addr)
    request.meta['proxy'] = 'http://{0}'.format(proxy_addr)

settings.py

这里才是关键,我们需要执行middlewares里面的HttpbinProxyMiddleware类下面的方法,这里需要注意的是我取消了下载中间件的retry中间件,因为scrapy本身就有自动重试的方法,为了试验效果,这里取消了默认的重试中间件。

DOWNLOADER_MIDDLEWARES = {
  'httpbin.middlewares.HttpbinProxyMiddleware': 543,
  #设置不参与scrapy的自动重试的动作
  'scrapy.downloadermiddlewares.retry.RetryMiddleware':None
}

注意:

上面我访问的url是httpbin.org,这个网站不用代理也可以打开,这里你可以在不打开FQ工具的时候,访问google.com,因为我自己学习用的代理地址基本都是国内的地址,所以即使是google也是打不开的。

总结:

上面我们介绍了两种scrapy加代理的写法:

1、第一种是直接每次访问都使用代理IP发起请求

2、第二种是在不能正常获取请求结果的时候,再使用代理ip。

3、我们学习了scrapy中如何打印logging日志,从而简单判断问题和执行步骤。

小知识:

['scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware',
 'scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware',
 'scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware',
 'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware',
 'httpbin.middlewares.HttpbinProxyMiddleware',
 'scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware',
 'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware',
 'scrapy.downloadermiddlewares.redirect.RedirectMiddleware',
 'scrapy.downloadermiddlewares.cookies.CookiesMiddleware',
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2017-11-27 23:36:47 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
 'scrapy.spidermiddlewares.offsite.OffsiteMiddleware',
 'scrapy.spidermiddlewares.referer.RefererMiddleware',
 'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware',
 'scrapy.spidermiddlewares.depth.DepthMiddleware']

这里我们可以再Terminal下面打印一下,简单介绍一下:

1、在scrapy中的中间件里面,对应的中间件后面的数字越小,执行优先级越高。

2、如果你想取消某个download_middlewares的话就直接如我上面写的,把它Copy出来,加个None,这样它就不执行了。

3、补充,如果你看过scrapy的基本执行流程图的话,就会知道scrapy除了下载中间件,还有个spider中间件,所以用的时候不要用错了。

D:\项目\小项目\scrapy_day6_httpbin\httpbin>scrapy settings --get=DOWNLOADER_MIDDLEWARES_BASE
{"scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware": 300, "scrapy.downloadermiddlewares.useragent.UserAgentMiddleware": 500, "scrapy.downloadermiddlewares.redirect.MetaRefres
hMiddleware": 580, "scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware": 900, "scrapy.downloadermiddlewares.redirect.RedirectMiddleware": 600, "scrapy.downloadermiddlewares.r
obotstxt.RobotsTxtMiddleware": 100, "scrapy.downloadermiddlewares.retry.RetryMiddleware": 550, "scrapy.downloadermiddlewares.cookies.CookiesMiddleware": 700, "scrapy.downloadermiddle
wares.defaultheaders.DefaultHeadersMiddleware": 400, "scrapy.downloadermiddlewares.stats.DownloaderStats": 850, "scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddlewar
e": 590, "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 750, "scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware": 350, "scrapy.downloadermiddlewar
es.ajaxcrawl.AjaxCrawlMiddleware": 560}

更多关于Python相关内容可查看本站专题:《Python Socket编程技巧总结》、《Python正则表达式用法总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python with statement 进行文件操作指南
Aug 22 Python
Python实现读取文件最后n行的方法
Feb 23 Python
基于Python_脚本CGI、特点、应用、开发环境(详解)
May 23 Python
Python定时发送消息的脚本:每天跟你女朋友说晚安
Oct 21 Python
pyinstaller打包程序exe踩过的坑
Nov 19 Python
对pytorch的函数中的group参数的作用介绍
Feb 18 Python
Python统计文本词汇出现次数的实例代码
Feb 27 Python
python 中的paramiko模块简介及安装过程
Feb 29 Python
在python中使用pyspark读写Hive数据操作
Jun 06 Python
python 解决selenium 中的 .clear()方法失效问题
Sep 01 Python
Django通过设置CORS解决跨域问题
Nov 26 Python
python链表类中获取元素实例方法
Feb 23 Python
Python中矩阵创建和矩阵运算方法
Aug 04 #Python
Python爬虫框架scrapy实现的文件下载功能示例
Aug 04 #Python
python生成1行四列全2矩阵的方法
Aug 04 #Python
查看python下OpenCV版本的方法
Aug 03 #Python
Python 使用PIL中的resize进行缩放的实例讲解
Aug 03 #Python
numpy中loadtxt 的用法详解
Aug 03 #Python
matplotlib给子图添加图例的方法
Aug 03 #Python
You might like
PHP使用GETDATE获取当前日期时间作为一个关联数组的方法
2015/03/19 PHP
PHP将URL转换成短网址的算法分享
2016/09/13 PHP
php类自动装载、链式操作、魔术方法实现代码
2017/07/23 PHP
php 读取文件夹下所有图片、文件的实例
2018/10/17 PHP
PHP使用 Imagick 扩展实现图片合成,圆角处理功能示例
2019/09/09 PHP
分享一个自定义的console类 让你不再纠结JS中的调试代码的兼容
2012/04/20 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
2014/04/04 Javascript
AMD异步模块定义介绍和Require.js中使用jQuery及jQuery插件的方法
2014/06/06 Javascript
javascript实现table表格隔行变色的方法
2015/05/13 Javascript
基于zepto的移动端轻量级日期插件--date_picker
2016/03/04 Javascript
Bootstrap多级菜单的实现代码
2017/05/23 Javascript
angular4模块中给标签添加背景图的实现方法
2017/09/15 Javascript
分享vue里swiper的一些坑
2018/08/30 Javascript
JavaScript实现筛选数组
2021/03/02 Javascript
Python3实现从指定路径查找文件的方法
2015/05/22 Python
Python实现字符串与数组相互转换功能示例
2017/09/22 Python
python实现图像识别功能
2018/01/29 Python
Python实现连接两个无规则列表后删除重复元素并升序排序的方法
2018/02/05 Python
python实现逆序输出一个数字的示例讲解
2018/06/25 Python
python 使用装饰器并记录log的示例代码
2019/07/12 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
2019/12/13 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
2020/04/10 Python
Python使用pyyaml模块处理yaml数据
2020/04/14 Python
简单聊聊H5的pushState与replaceState的用法
2018/04/03 HTML / CSS
htmlentities() 和 htmlspecialchars()有什么区别
2015/07/01 面试题
AJAX应用和传统Web应用有什么不同
2013/08/24 面试题
三项教育活动实施方案
2014/03/30 职场文书
大学学习计划书范文
2014/05/02 职场文书
纪念九一八事变演讲稿:勿忘国耻
2014/09/14 职场文书
门卫岗位职责
2015/02/09 职场文书
医院财务人员岗位职责
2015/04/14 职场文书
违反纪律检讨书范文
2015/05/07 职场文书
学雷锋感言
2015/08/03 职场文书
外科护士长工作总结
2015/08/12 职场文书
Python中快速掌握Data Frame的常用操作
2021/03/31 Python
python入门学习关于for else的特殊特性讲解
2021/11/20 Python