python爬虫框架scrapy代理中间件掌握学习教程

 更新时间:2021年11月15日 10:10:16   作者:梦想橡皮擦  
这篇文章主要介绍了python爬虫框架scrapy代理中间件掌握学习教程,为大家说明一下 scrapy 中代理相关知识点,有需要的朋友可以借鉴参考下,希望能够有所帮助

代理的使用场景

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

网络不好,需要代理;

目标站点国内访问不了,需要代理;

网站封杀了你的 IP,需要代理。

使用 HttpProxyMiddleware 中间件

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

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

修改代理的方式非常简单,只需要在 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']

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

以上就是python爬虫框架scrapy代理中间件掌握学习教程的详细内容,更多关于scrapy框架代理中间件学习的资料请关注脚本之家其它相关文章!

相关文章

  • Python图像处理之图像的读取、显示与保存操作【测试可用】

    Python图像处理之图像的读取、显示与保存操作【测试可用】

    这篇文章主要介绍了Python图像处理之图像的读取、显示与保存操作,结合实例形式分析了Python使用PIL模块、scipy和matplotlib模块进行图像读写、显示等相关操作技巧,需要的朋友可以参考下
    2019-01-01
  • Python使用Selenium实现浏览器打印预览功能

    Python使用Selenium实现浏览器打印预览功能

    在Web开发中,打印预览是一个常见的功能需求,通过打印预览,我们可以预览和调整网页的打印布局、样式和内容,Python的Selenium库是一个强大的工具,可以自动化浏览器操作,包括打印预览,本文将介绍如何使用Python Selenium库来实现浏览器的打印预览功能
    2023-11-11
  • python使用标准库根据进程名如何获取进程的pid详解

    python使用标准库根据进程名如何获取进程的pid详解

    Python有一套很有用的标准库(standard library)。标准库会随着Python解释器,一起安装在你的电脑中的,所以下面这篇文章主要给大家介绍了关于python使用标准库根据进程名如何获取进程pid的相关资料,需要的朋友可以参考下。
    2017-10-10
  • spark dataframe 将一列展开,把该列所有值都变成新列的方法

    spark dataframe 将一列展开,把该列所有值都变成新列的方法

    今天小编就为大家分享一篇spark dataframe 将一列展开,把该列所有值都变成新列的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Python 数据处理更容易的12个辅助函数总结

    Python 数据处理更容易的12个辅助函数总结

    Python的产生似乎就是专门用来处理数据的,顺理成章的成为大数据的主流语言,本文介绍十二个函数辅助你更容易更便捷的用Python进行数据处理
    2021-11-11
  • 详解Python 切片语法

    详解Python 切片语法

    Python的切片是特别常用的功能,主要用于对列表的元素取值。这篇文章主要介绍了详解Python 切片语法,需要的朋友可以参考下
    2019-06-06
  • 深入浅析Python 命令行模块 Click

    深入浅析Python 命令行模块 Click

    这篇文章主要介绍了Python 命令行模块 Click的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • Python 实现多表和工作簿合并及一表按列拆分

    Python 实现多表和工作簿合并及一表按列拆分

    这篇文章主要介绍了Python 实现多表和工作簿合并及一表按列拆分,文章围绕主题展开详细的资料介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-05-05
  • python 判断是否为正小数和正整数的实例

    python 判断是否为正小数和正整数的实例

    这篇文章主要介绍了python 判断是否为正小数和正整数的实例的相关资料,这里提供实例,实例注释说明很清楚,需要的朋友可以参考下
    2017-07-07
  • python图像填充与裁剪/resize的实现代码

    python图像填充与裁剪/resize的实现代码

    这篇文章主要介绍了python图像填充与裁剪/resize,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08

最新评论