HTTP代理服务器可以比作客户端与Web服务器网站之间的一个信息中转站,客户端发送的HTTP请求和Web服务器返回的HTTP响应通过代理服务器转发给对方,

爬虫程序在爬取某些网站的时候也需要使用代理,例如

  • 由于网络环境因素,直接爬取的速度太慢了,使用代理提高爬取的速度
  • 某些网站读用户的访问速度进行限制,爬取过快会被封禁IP,使用代理防止被封禁
  • 由于地方法律或者政治的原因,某些网站是无法直接进行访问的,使用代理可以绕过访问的限制

在scrapy中专门提供了HttpProxyMiddleware来给scrapy爬虫设置代理

  

HttpProxyMiddleware默认就是开启的,它会在系统环境变量中搜索当前系统代理,作为scrapy爬虫使用的代理

源码解析:

  __init__方法:

    在HttpProxyMiddleware的构造器中,使用python标准库urllib中的getproxies函数在系统环境变量中搜索系统代理的相关配置(变量名格式为[格式]_proxy的变量),调用self._get_proxy方法解析代理配置信息,并将其返回结果保存到self.proxies字典中,如果没有找到任何代理配置的话,就抛出NotConfigured异常,HttpProxyMiddleware就会被放弃使用

  _get_proxy方法:

    解析代理配置信息,返回身份验证信息以及代理服务器url

  process_request方法

    处理每一个待发送的请求,为没有设置过代理的请求(meta属性不包含proxy字段的请求)调用self.set_proxy方法设置代理

  _set_proxy方法

    为一个请求设置代理,以请求的协议(HTTP或者HTTPS)作为键,从代理服务器信息字典self.proxies中选择代理,赋给request.meta的proxy字段。对于身份需要验证的代理服务器,添加HTTP头部Proxy-Authorization,他的值是在_get_proxy方法中计算得到的。

总结:

  在scrapy中为一个请求设置代理就是将代理服务器的url写到request.meta['proxy']中

使用多个代理:

  利用HttpProxyMiddleware为爬虫设置代理的时候,对于一种协议(HTTPShuozheHTTP)的所有请求只能使用一个代理,如果想使用多个代理,可以在构造每一个Request对象的时候,通过meta参数的proxy字段手动进行设置

import scrapy
from scrapy import Request
import json
class XiciSpider(scrapy.Spider):
name = "xici_proxy"
allowed_domains = ["www.xicidaili.com"]
def start_requests(self): #爬取http://www.xicidaili.com/nn/前3 页 foriin range(1, 4):
yield Request('http://www.xicidaili.com/nn/%s' % i)
def parse(self, response):
for sel in response.xpath('//table[@id="ip_list"]/tr[pos
# 提取代理的IP、port、scheme(http or https)
ip = sel.css('td:nth-child(2)::text').extract_first()
port = sel.css('td:nth-child(3)::text').extract_first()
scheme = sel.css('td:nth-child(6)::text').extract_first()
# 使用爬取到的代理再次发送请求到http(s)://httpbin.org/ip url = '%s://httpbin.org/ip' % scheme
proxy = '%s://%s:%s' % (scheme, ip, port)
meta = {
'proxy': proxy,
'dont_retry': True,
'download_timeout': 10,
# 以下两个字段是传递给check_available 方法的信息,方便 '_proxy_scheme': scheme,
'_proxy_ip': ip,
}
yield Request(url, callback=self.check_available, meta=meta, dont_filter=True)
def check_available(self, response): proxy_ip = response.meta['_proxy_ip']
# 判断代理是否具有隐藏IP 功能
if proxy_ip == json.loads(response.text)['origin']:
yield {
'proxy_scheme': response.meta['_proxy_scheme'], 'proxy': response.meta['proxy'],
}
  • 在start_requests中请求网站下的前三页,用parse方法作为页面解析的函数
  • 在parse方法中提取一个页面中的所有的代理服务器信息,由于这些代理未必都是可用的,所以使用采集到的代理发送请求http(s)://httpbin.org/ip验证其是否可用,用check_acailable方法作为页面的解析函数
  • 要是能够执行到check_available方法,那么也就意味着response中对应的请求所使用的代理都是可用的,在check_available方法中,通过响应json字符串中的origin字段可以判断代理是否是匿名的(隐藏IP),返回匿名代理。

使用HTTP代理的更多相关文章

  1. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  2. nginx配置反向代理或跳转出现400问题处理记录

    午休完上班后,同事说测试站点访问接口出现400 Bad Request  Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...

  3. Visual Studio Code 代理设置

    Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...

  4. DynamicObject - 代理对象的种类

    开箱即用,DynamicProxy提供了多种代理对象,主要分成两个大类: 基于继承(Inheritance-based) 基于继承的代理是通过继承一个代理类来实现,代理拦截对类的虚(virtual)成 ...

  5. SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论

    异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 后台创建了一个DntHub的集线器 前台在调用的时候出现了问题(经检查是代理对象 ...

  6. 实现代理设置proxy

    用户在哪些情况下是需要设置网络代理呢? 1. 内网上不了外网,需要连接能上外网的内网电脑做代理,就能上外网:多个电脑共享上外网,就要用代理: 2.有些网页被封,通过国外的代理就能看到这被封的网站:3. ...

  7. 23种设计模式--代理模式-Proxy

    一.代理模式的介绍       代理模式我们脑袋里出现第一个词语就是代购,其实就是这样通过一个中间层这个中间成是属于什么都干什么都买得,俗称"百晓生",在平时得开发中我们经常会听到 ...

  8. 使用Java原生代理实现AOP

    ### 本文由博主柒.原创,转载请注明出处 ### 完整源码下载地址 [https://github.com/MatrixSeven/JavaAOP](https://github.com/Matri ...

  9. Javascript 代理模式模拟一个文件同步功能

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. [原]HAproxy 代理技术原理探究

    HAproxy 技术分享 简介 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件 Features 1.免费 2.能够做到4层以上代理 3.高性能 ...

随机推荐

  1. 2019-5-21-win10-uwp-xaml-兼容多个版本条件编译

    title author date CreateTime categories win10 uwp xaml 兼容多个版本条件编译 lindexi 2019-5-21 11:19:3 +0800 20 ...

  2. activemq设置后台管理用户名密码,及生产者消息密码

    activemq设置后台管理用户名密码,及生产者消息密码 1.修改conf/activemq.xml 在<broker>标签下,找到</shutdownHooks>标签.在这个 ...

  3. AOP与IOC的概念(即spring的核心)

    a) IOC:Spring是开源框架,使用框架可以使我们减少工作量,提高工作效率并且它是分层结构,即相对应的层处理对应的业务逻辑,减少代码的耦合度.而spring的核心是IOC控制反转和AOP面向切面 ...

  4. 06.Mybatis关联查询

    1.一对一关联查询 需求:查询出每条orders记录和其关联的user信息 在orders实体类中添加属性与set.get方法 /** * 测试1对1关联查询 */ private User user ...

  5. python的异常捕捉

    你可能会说既然有万能异常Exception,那么我直接用上面的这种形式就好了,其他异常可以忽略 你说的没错,但是应该分两种情况去看 1.如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一 ...

  6. 字体jquery ---

    You don’t need icons! Here are 100+ unicode symbols that you can use Danny Markov December 3rd, 2014 ...

  7. mkdir: Cannot create directory /file. Name node is in safe mode.

    刚刚在hadoop想创建一个目录的时候,发现报错了 具体信息如下: [hadoop@mini1 hadoop-2.6.4]$ hadoop fs -mkdir /file mkdir: Cannot ...

  8. 暴力剪枝——cf1181C

    暴力求长度为len时,以i,j为左上角的旗子的数量 不剪枝的话复杂度是n*n*m*n,必定超时 两个可以剪枝的地方:如果格子[i,j]可以作为长度为len的旗子的左上角,那么其必定不可以作为长度> ...

  9. 使用treeNMS管理及监控Redis

    Redis做为现在web应用开发的黄金搭担组合,大量的被应用,广泛用于存储session信息,权限信息,交易作业等热数据.做为一名有10年以上JAVA开发经验的程序员,工作中项目也是广泛使用了Redi ...

  10. laravel装饰者模式例子

    interface Decorator{ public function display(); } class XiaoFang implements Decorator { private $nam ...