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中open函数的使用
Mar 01 Python
Python中list初始化方法示例
Sep 18 Python
Python中常用的8种字符串操作方法
May 06 Python
Django models.py应用实现过程详解
Jul 29 Python
Python多叉树的构造及取出节点数据(treelib)的方法
Aug 09 Python
使用Python的datetime库处理时间(RPA流程)
Nov 24 Python
tensorflow模型保存、加载之变量重命名实例
Jan 21 Python
Pytorch 使用 nii数据做输入数据的操作
May 26 Python
Python分析最近大火的网剧《隐秘的角落》
Jul 02 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
Nov 02 Python
matplotlib制作雷达图报错ValueError的实现
Jan 05 Python
Python 绘制多因子柱状图
May 11 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边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
php无限极分类递归排序实现方法
2014/11/11 PHP
浅谈PHP5.6 与 PHP7.0 区别
2019/10/09 PHP
Code:loadScript( )加载js的功能函数
2007/02/02 Javascript
转换json格式的日期为Javascript对象的函数
2010/07/13 Javascript
jQuery EasyUI API 中文文档 - Documentation 文档
2011/09/29 Javascript
jQuery插件开发全解析
2012/10/10 Javascript
js语法学习之判断一个对象是否为数组
2014/05/13 Javascript
jQuery超简单选项卡完整实例
2015/09/26 Javascript
Javascript实现的SHA-256加密算法完整实例
2016/02/02 Javascript
JSON简介以及用法汇总
2016/02/21 Javascript
H5移动端适配 Flexible方案
2016/10/24 Javascript
ES6 迭代器与可迭代对象的实现
2019/02/11 Javascript
js回文数的4种判断方法示例
2019/06/04 Javascript
jQuery实现电梯导航模块
2020/12/22 jQuery
[01:50:49]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第三场 1月24日
2021/03/11 DOTA
Python中列表元素转为数字的方法分析
2016/06/14 Python
numpy和pandas中数组的合并、拉直和重塑实例
2019/06/28 Python
深入浅出CSS3 background-clip,background-origin和border-image教程
2011/01/27 HTML / CSS
Fairyseason:为个人和批发商提供女装和配件
2017/03/01 全球购物
英国著名的小众美容品牌网站:Alyaka
2017/08/08 全球购物
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
澳洲小众品牌的集合网站:BNKR
2018/02/23 全球购物
苹果台湾官网:Apple台湾
2019/01/05 全球购物
自荐信格式技巧有哪些呢
2013/11/19 职场文书
计算机专业毕业生求职信分享
2013/12/24 职场文书
ktv中秋节活动方案
2014/01/30 职场文书
集团公司党的群众路线教育实践活动工作总结
2014/03/03 职场文书
2014年社区庆元旦活动方案
2014/03/08 职场文书
转让协议书
2015/01/27 职场文书
开会通知
2015/04/20 职场文书
爱心捐书倡议书
2015/04/27 职场文书
导游词之广西漓江
2019/11/02 职场文书
mysql中varchar类型的日期进行比较、排序等操作的实现
2021/11/17 MySQL
webpack介绍使用配置教程详解webpack介绍和使用
2022/06/25 Javascript