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深入学习之上下文管理器
Aug 31 Python
Python实现的ini文件操作类分享
Nov 20 Python
Python中使用Flask、MongoDB搭建简易图片服务器
Feb 04 Python
Python脚本文件打包成可执行文件的方法
Jun 02 Python
python3设计模式之简单工厂模式
Oct 17 Python
python获取多线程及子线程的返回值
Nov 15 Python
在CentOS6上安装Python2.7的解决方法
Jan 09 Python
解析Python的缩进规则的使用
Jan 16 Python
Win10系统下安装labelme及json文件批量转化方法
Jul 30 Python
Python对接支付宝支付自实现功能
Oct 10 Python
解决pyCharm中 module 调用失败的问题
Feb 12 Python
详解python百行有效代码实现汉诺塔小游戏(简约版)
Oct 30 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中mysql_field_type()函数用法
2014/11/24 PHP
[原创]PHP实现逐行删除文件右侧空格的方法
2015/12/25 PHP
php 一维数组的循环遍历实现代码
2017/04/10 PHP
PHP新特性之字节码缓存和内置服务器
2017/08/11 PHP
理解Javascript_02_理解undefined和null
2010/10/11 Javascript
JavaScript中的console.group()函数详细介绍
2014/12/29 Javascript
JavaScript 模块化编程(笔记)
2015/04/08 Javascript
Javascript实现图片轮播效果(二)图片序列节点的控制实现
2016/02/17 Javascript
详解nodejs中exports和module.exports的区别
2017/02/17 NodeJs
关于vue.js组件数据流的问题
2017/07/26 Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
2018/01/21 Javascript
VUE简单的定时器实时刷新的实现方法
2019/01/20 Javascript
微信小程序如何自定义table组件
2019/06/29 Javascript
Bootstrap实现省市区三级联动(亲测可用)
2019/07/26 Javascript
JS原型和原型链原理与用法实例详解
2020/02/05 Javascript
JSONP 的原理、理解 与 实例分析
2020/05/16 Javascript
JS 5种遍历对象的方式
2020/06/16 Javascript
JavaScript实现烟花绽放动画效果
2020/08/04 Javascript
Python及Django框架生成二维码的方法分析
2018/01/31 Python
python队列queue模块详解
2018/04/27 Python
python标记语句块使用方法总结
2019/08/05 Python
python 实现dict转json并保存文件
2019/12/05 Python
python matplotlib 绘图 和 dpi对应关系详解
2020/03/14 Python
解决pycharm导入numpy包的和使用时报错:RuntimeError: The current Numpy installation (‘D:\\python3.6\\lib\\site-packa的问题
2020/12/08 Python
python 邮件检测工具mmpi的使用
2021/01/04 Python
python使用scapy模块实现ARP扫描的过程
2021/01/21 Python
CSS3制作缩略图的详细过程
2016/07/08 HTML / CSS
C#如何调用Word并打开一个Word文档
2013/05/08 面试题
优秀管理者获奖感言
2014/02/17 职场文书
警校毕业生自我评价
2014/04/06 职场文书
大学生活自我评价
2014/04/09 职场文书
社会工作专业求职信
2014/07/15 职场文书
护士节活动总结
2014/08/29 职场文书
python如何正确使用yield
2021/05/21 Python
使用Spring处理x-www-form-urlencoded方式
2021/11/02 Java/Android
Mysql 文件配置解析介绍
2022/05/06 MySQL