资讯专栏INFORMATION COLUMN

python scrapy 代理中间件,爬虫必掌握的内容之一

binta / 1504人阅读

摘要:使用中间件本次的测试站点依旧使用,通过访问可以获取当前请求的地址。中间件默认是开启的,可以查看其源码重点为方法。修改代理的方式非常简单,只需要在请求创建的时候,增加参数即可。接下来将可用的代理保存到文件中。同步修改文件中的代码。

本篇博客为大家说明一下 scrapy 中代理相关知识点。

代理的使用场景

编写爬虫代码的程序员,永远绕不开就是使用代理,在编码过程中,你会碰到如下情形:

  1. 网络不好,需要代理;
  2. 目标站点国内访问不了,需要代理;
  3. 网站封杀了你的 IP,需要代理。

使用 HttpProxyMiddleware 中间件

本次的测试站点依旧使用 http://httpbin.org/,通过访问 http://httpbin.org/ip 可以获取当前请求的 IP 地址。
HttpProxyMiddleware 中间件默认是开启的,可以查看其源码重点为 process_request() 方法。

修改代理的方式非常简单,只需要在 Requests 请求创建的时候,增加 meta 参数即可。

import scrapyclass 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 scrapyclass 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 scrapyclass 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 HttpProxyMiddlewarefrom collections import defaultdictimport randomclass 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"]

如果你想测试爬虫,可编写一个随机返回请求代理的函数,将其用到任意爬虫代码之上,完成本博客任务。

收藏时间

本期博客收藏过 400,立刻更新下一篇

今天是持续写作的第 261 / 200 天。
可以关注我,点赞我、评论我、收藏我啦。

更多精彩


???扫码加入【78技术人】~ Python 事业部???,源码也在这

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/123376.html

相关文章

  • 网络爬虫介绍

    摘要:什么是爬虫网络爬虫也叫网络蜘蛛,是一种自动化浏览网络的程序,或者说是一种网络机器人。 什么是爬虫 网络爬虫也叫网络蜘蛛,是一种自动化浏览网络的程序,或者说是一种网络机器人。它们被广泛用于互联网搜索引擎或其他类似网站,以获取或更新这些网站的内容和检索方式。它们可以自动采集所有其能够访问到的页面内容,以供搜索引擎做进一步处理(分检整理下载的页面),而使得用户能更快的检索到他们需要的信息。简...

    sf190404 评论0 收藏0
  • 精通Python网络爬虫(0):网络爬虫学习路线

    摘要:以上是如果你想精通网络爬虫的学习研究路线,按照这些步骤学习下去,可以让你的爬虫技术得到非常大的提升。 作者:韦玮 转载请注明出处 随着大数据时代的到来,人们对数据资源的需求越来越多,而爬虫是一种很好的自动采集数据的手段。 那么,如何才能精通Python网络爬虫呢?学习Python网络爬虫的路线应该如何进行呢?在此为大家具体进行介绍。 1、选择一款合适的编程语言 事实上,Python、P...

    spacewander 评论0 收藏0
  • Python爬虫Scrapy学习(基础篇)

    摘要:下载器下载器负责获取页面数据并提供给引擎,而后提供给。下载器中间件下载器中间件是在引擎及下载器之间的特定钩子,处理传递给引擎的。一旦页面下载完毕,下载器生成一个该页面的,并将其通过下载中间件返回方向发送给引擎。 作者:xiaoyu微信公众号:Python数据科学知乎:Python数据分析师 在爬虫的路上,学习scrapy是一个必不可少的环节。也许有好多朋友此时此刻也正在接触并学习sc...

    pkhope 评论0 收藏0
  • 从零开始Python爬虫速成指南

    摘要:内容如下是我们准备爬的初始页这个是解析函数,如果不特别指明的话,抓回来的页面会由这个函数进行解析。爬取多个页面的原理相同,注意解析翻页的地址设定终止条件指定好对应的页面解析函数即可。后面的数字表示的是优先级。指明每两个请求之间的间隔。 序 本文主要内容:以最短的时间写一个最简单的爬虫,可以抓取论坛的帖子标题和帖子内容。 本文受众:没写过爬虫的萌新。 入门 0.准备工作 需要准备的东西:...

    gotham 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<