python爬虫框架scrapy代理中间件掌握学习教程
作者:梦想橡皮擦 发布时间:2021-03-22 15:34:54
标签:python,scrapy,中间件
代理的使用场景
编写爬虫代码的程序员,永远绕不开就是使用代理,在编码过程中,你会碰到如下情形:
网络不好,需要代理;
目标站点国内访问不了,需要代理;
网站封杀了你的 IP,需要代理。
使用 HttpProxyMiddleware 中间件
本次的测试站点依旧使用 http://httpbin.org/
,通过访问 http://httpbin.org/ip 可以获取当前请求的 IP 地址。
HttpProxyMiddleware 中间件默认是开启的,可以查看其源码重点为 process_request()
方法。
修改代理的方式非常简单,只需要在 Requests
请求创建的时候,增加 meta
参数即可。
import scrapy
class PtSpider(scrapy.Spider):
name = 'pt'
allowed_domains = ['httpbin.org']
start_urls = ['http://httpbin.org/ip']
def start_requests(self):
yield scrapy.Request(url=self.start_urls[0], meta={'proxy': 'http://202.5.116.49:8080'})
def parse(self, response):
print(response.text)
接下来通过获取一下 https://www.kuaidaili.com/free/
网站的代理 IP,并测试其代理是否可用。
import scrapy
class PtSpider(scrapy.Spider):
name = 'pt'
allowed_domains = ['httpbin.org', 'kuaidaili.com']
start_urls = ['https://www.kuaidaili.com/free/']
def parse(self, response):
IP = response.xpath('//td[@data-title="IP"]/text()').getall()
PORT = response.xpath('//td[@data-title="PORT"]/text()').getall()
url = 'http://httpbin.org/ip'
for ip, port in zip(IP, PORT):
proxy = f"http://{ip}:{port}"
meta = {
'proxy': proxy,
'dont_retry': True,
'download_timeout': 10,
}
yield scrapy.Request(url=url, callback=self.check_proxy, meta=meta, dont_filter=True)
def check_proxy(self, response):
print(response.text)
接下来将可用的代理 IP 保存到 JSON 文件中。
import scrapy
class PtSpider(scrapy.Spider):
name = 'pt'
allowed_domains = ['httpbin.org', 'kuaidaili.com']
start_urls = ['https://www.kuaidaili.com/free/']
def parse(self, response):
IP = response.xpath('//td[@data-title="IP"]/text()').getall()
PORT = response.xpath('//td[@data-title="PORT"]/text()').getall()
url = 'http://httpbin.org/ip'
for ip, port in zip(IP, PORT):
proxy = f"http://{ip}:{port}"
meta = {
'proxy': proxy,
'dont_retry': True,
'download_timeout': 10,
'_proxy': proxy
}
yield scrapy.Request(url=url, callback=self.check_proxy, meta=meta, dont_filter=True)
def check_proxy(self, response):
proxy_ip = response.json()['origin']
if proxy_ip is not None:
yield {
'proxy': response.meta['_proxy']
}
同时修改 start_requests
方法,获取 10 页代理。
class PtSpider(scrapy.Spider):
name = 'pt'
allowed_domains = ['httpbin.org', 'kuaidaili.com']
url_format = 'https://www.kuaidaili.com/free/inha/{}/'
def start_requests(self):
for page in range(1, 11):
yield scrapy.Request(url=self.url_format.format(page))
实现一个自定义的代理中间件也比较容易,有两种办法,第一种继承 HttpProxyMiddleware
,编写如下代码:
from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
from collections import defaultdict
import random
class RandomProxyMiddleware(HttpProxyMiddleware):
def __init__(self, auth_encoding='latin-1'):
self.auth_encoding = auth_encoding
self.proxies = defaultdict(list)
with open('./proxy.csv') as f:
proxy_list = f.readlines()
for proxy in proxy_list:
scheme = 'http'
url = proxy.strip()
self.proxies[scheme].append(self._get_proxy(url, scheme))
def _set_proxy(self, request, scheme):
creds, proxy = random.choice(self.proxies[scheme])
request.meta['proxy'] = proxy
if creds:
request.headers['Proxy-Authorization'] = b'Basic ' + creds
代码核心重写了 __init__
构造方法,并重写了 _set_proxy
方法,在其中实现了随机代理获取。
同步修改 settings.py
文件中的代码。
DOWNLOADER_MIDDLEWARES = {
'proxy_text.middlewares.RandomProxyMiddleware': 543,
}
创建一个新的代理中间件类
class NRandomProxyMiddleware(object):
def __init__(self, settings):
# 从settings中读取代理配置 PROXIES
self.proxies = settings.getlist("PROXIES")
def process_request(self, request, spider):
request.meta["proxy"] = random.choice(self.proxies)
@classmethod
def from_crawler(cls, crawler):
if not crawler.settings.getbool("HTTPPROXY_ENABLED"):
raise NotConfigured
return cls(crawler.settings)
可以看到该类从 settings.py
文件中的 PROXIES
读取配置,所以修改对应配置如下所示:
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None,
'proxy_text.middlewares.NRandomProxyMiddleware': 543,
}
# 代码是前文代码采集的结果
PROXIES = ['http://140.249.48.241:6969',
'http://47.96.16.149:80',
'http://140.249.48.241:6969',
'http://47.100.14.22:9006',
'http://47.100.14.22:9006']
如果你想测试爬虫,可编写一个随机返回请求代理的函数,将其用到任意爬虫代码之上,完成本博客任务。
来源:https://blog.csdn.net/hihell/article/details/121012464
0
投稿
猜你喜欢
- 1、DOMWEB标准现在可真是热门中热门,不过下面讨论的是一个不符合标准的document.all[]。DOM--DOCUMENTOBJEC
- 今天萌发一个想法,用css来实现透视效果。起初,我想到的是我们常见的添加阴影效果的方法,用多个div通过偏移来实现,但这需要很多 div,不
- 平时我们获取事件对象一般写法如下:function getEvent(event) { return event
- 先简单说一下MP3的ID3 标记,因为主要是操作这个玩意MP3最开始的时候没有我们今天看到的那样,有歌手、年代,专集等等信息只有一些简单的参
- PDO::quotePDO::quote — 为SQL语句中的字符串添加引号。(PHP 5 >= 5.1.0, PECL pdo &g
- 小的本身是一个平面设计人员,前一阵儿有一些空闲的时间,便在各个站长网上发布了贴子,大意是免费制作logo,以换取网站连接(相信很多人都看过)
- Python中编码问题:u'\xe6\x97\xa0\xe5\x90\x8d' 类型的转为utf-8的解决办法相信小伙伴们遇
- 现在IE7已经推出一段时间并且渗透到用户当中,不用等太久我们就可以在页面上使用更高级的CSS。两个最有用的项目将是 Child子和Adjac
- 一、介绍QQ空间相册的个性化利器,能对照片进行效果的优化、文字编辑等等。从设计上使用了创新的手法,尽量减少用户的思考。其中,通过界面的特殊表
- 很简单,只需建立一个worksheet和Excel相关的信息就可以了具体代码见下:<%set xlApp =&nb
- Oracle客户端NLS_LANG设置 OracleWindowsMicrosoftUnixBash 1. NLS_LANG 参数组成 NL
- 阅读上一篇:成为一个顶级设计师的第一准则限制你的色彩成为一个顶级设计师的7个简单原则的第二部分限制使用你的色彩。好象上个准则是让你限制用你的
- aspjpeg组件官方下载地址:http://www.persits.com/说明: 1、aspjpeg能对图片水印进行透明度调整
- 在asp中获取当前的地址栏网址很简单,使用下面这句语句即能实现获取网站域名Request.ServerVariables("HTT
- 本文实例为大家分享了python实现最速下降法的具体代码,供大家参考,具体内容如下代码:from sympy import *import
- 浏览器对于CSS的支持问题落后于CSS的发展,以占有市场绝对份额的Internet Explorer来说,直到其前不久发布的第8个版本才刚刚
- 即使页面上只有一个元素它也是一个矩形的盒模型。其大小、位置、行为都可以通过CSS来控制。这里的行为是指当盒模型内部以及周围的内容发生变化时的
- 由于 window.onload 事件需要在页面所有内容(包括图片等)加载完后,才执行,但往往我们更希望在 DOM 一加载完就执行脚本。其实
- PHP生成桌面快捷方式就是这么的简单,大家生成的时候改下你要生成的网站即可。dianji.html代码:<a href="a
- 当变量维数加大时很难想象是怎样按不同维度求和的,高清楚一个,其他的应该就很清楚了,什么都不说了,上例子,例子一看便明白…..a=range(