使用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),返回匿名代理。
使用HTTP代理的更多相关文章
- 【原】谈谈对Objective-C中代理模式的误解
[原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...
- nginx配置反向代理或跳转出现400问题处理记录
午休完上班后,同事说测试站点访问接口出现400 Bad Request Request Header Or Cookie Too Large提示,心想还好是测试服务器出现问题,影响不大,不过也赶紧上 ...
- Visual Studio Code 代理设置
Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...
- DynamicObject - 代理对象的种类
开箱即用,DynamicProxy提供了多种代理对象,主要分成两个大类: 基于继承(Inheritance-based) 基于继承的代理是通过继承一个代理类来实现,代理拦截对类的虚(virtual)成 ...
- SignalR代理对象异常:Uncaught TypeError: Cannot read property 'client' of undefined 推出的结论
异常汇总:http://www.cnblogs.com/dunitian/p/4523006.html#signalR 后台创建了一个DntHub的集线器 前台在调用的时候出现了问题(经检查是代理对象 ...
- 实现代理设置proxy
用户在哪些情况下是需要设置网络代理呢? 1. 内网上不了外网,需要连接能上外网的内网电脑做代理,就能上外网:多个电脑共享上外网,就要用代理: 2.有些网页被封,通过国外的代理就能看到这被封的网站:3. ...
- 23种设计模式--代理模式-Proxy
一.代理模式的介绍 代理模式我们脑袋里出现第一个词语就是代购,其实就是这样通过一个中间层这个中间成是属于什么都干什么都买得,俗称"百晓生",在平时得开发中我们经常会听到 ...
- 使用Java原生代理实现AOP
### 本文由博主柒.原创,转载请注明出处 ### 完整源码下载地址 [https://github.com/MatrixSeven/JavaAOP](https://github.com/Matri ...
- Javascript 代理模式模拟一个文件同步功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [原]HAproxy 代理技术原理探究
HAproxy 技术分享 简介 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件 Features 1.免费 2.能够做到4层以上代理 3.高性能 ...
随机推荐
- The linux command 之进程
******************查看进程********************* 一.使用ps命令 [me@linuxbox ~]$ ps PID TTY TIME CMD pts/ :: ba ...
- Android Studio 配置快速生成模板代码
前言 Android studio 有提供快速生成模板代码的功能,其实这个功能也可以自定义配置.此篇博客将讲解如何使用此功能 进入Settings 选择 Editor > Live Templa ...
- Java类加载器浅述
jdk默认提供了三种类加载器: 1.Bootstrap ClassLoader(引导类加载器): 将<JAVA_HOME>\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库, ...
- 关于Qt5(1)-- 两个窗口互相切换的例子
<QT Creator快速入门>这本书有一章介绍model和modeless的概念时,用到了两个窗口互相切换的例子.但是原文对该例子的说明非常模糊不清,现整理如下. 1,要求:登陆界面.主 ...
- 校园商铺-4店铺注册功能模块-5店铺注册之Service层的实现
1. 创建接口 ShopService.java package com.csj2018.o2o.service; import java.io.File; import com.csj2018.o2 ...
- day12 bash中的if、for
bash 变量bash 定义:x= 作用:记录状态 规则:字母开头,后面可以接字母.数字.下划线 export args:将变量定义为全局变量 $$[]:括号中可以进行简单的数学整数运算,可以用ech ...
- bfs理解——hdu6386好题
用队列维护,对于每块颜色相同的相连的边进行dfs并记录即可 注意这题要用vis来标记边,不可以标记点 因为点的深度是可以随时更新的(这样的做法不满足贪心条件) #include<bits/std ...
- [NOI2007]生成树计数环形版
NOI2007这道题人类进化更完全之后出现了新的做法 毕姥爷题解: 于是毕姥爷出了一道环形版的这题(test0814),让我们写这个做法 环形的情况下,k=5的时候是162阶递推. 求这个递推可以用B ...
- error C2220: warning treated as error - no object file generated的处理方法
WDK/DDK中掉 error C2220: warning treated as error - no 'object' file generated 2009-04-01 15:54 网上搜索而来 ...
- ps快速将白底图片变为透明图片
方法一: 如果图层有锁图标,则要点击它,然它消失.然后选中魔棒工具,然后点击图片上要透明的区域,按下backspace键即可. 方法二: 转载自:https://blog.csdn.net/sunyi ...