使用HTTP代理
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),返回匿名代理。
最新文章
- C# 反射创建对象,包括创建引用外部程序集类的实例
- BFPRT(线性查找算法)
- PostgreSQL中,如何查表属于哪个数据库
- html跳转到同一个页面的不同位置
- iOS-Core Text 入门
- Algorithm -->; 字符串中最长不重合子串长度
- [leetcode]25. Reverse Nodes in k-Group每k个节点反转一下
- 小程序模板中data传值有无...
- JVM调优原理
- 更改Outlook 2013中Exchange数据文件存放路径
- Maven项目继承与聚合
- hdu3974 Assign the task【线段树】
- java 判断字符串IP合法性以及获取IP的数值形式
- typescript-dva脚手架
- SNMP TRAP报文解析
- jenkins配置01--用户添加及权限配置
- 关于GCD的几个结论
- python使用virtualenv
- javascript转换日期字符串为Date对象
- Javaee项目经验须知
热门文章
- JS对象 字符串分割 split() 方法将字符串分割为字符串数组,并返回此数组。 语法: stringObject.split(separator,limit)
- 修改jupyter保存文件目录
- Python基础知识之5——函数基础
- 解决Keep-Alive 和 Close 不能使用此属性设置
- Python学习笔记(四)——文件永久存储
- JSF(JavaServer Faces)简介
- 使用串口绘制实时曲线 —— SerialChart
- Spark 读写数据、抽象转换 拾遗
- [kuangbin带你飞]专题一 简单搜索 - D - Fliptile
- 数据类中引用virtual