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

yizhihongxing

Python爬虫框架Scrapy代理中间件掌握学习教程

在进行爬虫开发时,经常需要使用代理来避免IP被封锁或者提高爬取效率。而Scrapy是一个功能强大的Python爬虫框架,也提供了代理中间件这一强大的功能以支持代理。

代理中间件的使用方法

Scrapy提供了一个内置的代理中间件,可以通过在项目设置中设置代理中间件的位置及相应的参数,来让Scrapy使用代理。

以下是在Scrapy项目的settings.py中加入代理中间件的配置方法:

DOWNLOADER_MIDDLEWARES = {
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware': None, #禁用默认的代理中间件
    'scrapy_proxy_pool.middlewares.ProxyPoolMiddleware': 610, #启用代理池中间件
    'scrapy_proxy_pool.middlewares.BanDetectionMiddleware': 620, #启用ban检测中间件
}
# scrapy-proxy-pool是一个常用的代理池,可通过pip安装
PROXY_POOL_ENABLED = True

以上配置中,我们禁用了Scrapy默认的代理中间件(内置的HttpProxyMiddleware和RetryMiddleware),启用了第三方的代理池中间件scrapy-proxy-pool,并设置了其在下载器中的顺序。

需要注意的是,要在使用代理之前先安装代理池模块 scrapy-proxy-pool

示例1:使用代理IP池来爬取网站

假设我们要使用代理来爬取一个目标网站,我们可以创建一个新的scrapy项目进行实验。以下是项目的目录结构(省略了一些不必要的文件和目录):

scrapy-proxy-example/
    scrapy.cfg
    proxy_example/
        __init__.py
        items.py
        middlewares.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            my_spider.py

首先,我们在settings.py中添加上述代理中间件配置。

然后,我们需要在middlewares.py中编写代理中间件,用来从代理池中获取IP,并添加到请求中:

import requests
from scrapy import signals
from scrapy.exceptions import NotConfigured
from scrapy.http import HtmlResponse
from fake_useragent import UserAgent

class ProxyPoolMiddleware(object):
    proxy_url = 'http://127.0.0.1:5555/random'

    def __init__(self):
        self.proxy = None

    def process_request(self, request, spider):
        if self.proxy and self._check_proxy(self.proxy):
            request.meta['proxy'] = self.proxy
        else:
            self.proxy = requests.get(self.proxy_url).text.strip()
            request.meta['proxy'] = self.proxy

    def process_response(self, request, response, spider):
        return response

    def process_exception(self, request, exception, spider):
        if self.proxy and self._check_proxy(self.proxy):
            request.meta['proxy'] = self.proxy
            return request
        else:
            self.proxy = requests.get(self.proxy_url).text.strip()
            request.meta['proxy'] = self.proxy
            return request

    def _check_proxy(self, proxy):
        try:
            requests.get('https://www.baidu.com/', proxies={'https': 'https://{}'.format(proxy)}, timeout=3)
            return True
        except:
            return False

在这个中间件中,我们定义了一个代理URL(proxy_url),每次发起请求时都会从这个URL获取一个新的代理IP。如果已经有可用的代理IP,则直接使用,否则通过请求获取新的IP,并设置到request.meta['proxy']中。

接下来,我们来创建一个Spider文件(my_spider.py)来爬取目标网站,使用刚刚编写的代理中间件,以下是my_spider.py的代码:

import scrapy
from proxy_example.items import ProxyExampleItem

class MySpider(scrapy.Spider):
    name = 'my_spider'
    allowed_domains = ['target_site.com']
    start_urls = ['https://www.target_site.com/']

    def parse(self, response):
        # 在这里解析网页内容
        pass

在Spider中,我们只关注如何解析目标网站的内容,而不用关心如何获取代理IP。

以上就是使用代理IP池来爬取网站的完整示例,如果需要获取更多代理IP池的使用信息,可以参考文献中提供的相关链接。

示例2:使用隧道代理来爬取网站

使用隧道代理是一种常见的代理方式,它可以让我们通过隧道链接来获取代理IP。以下是如何使用隧道代理来爬取网站的示例:

我们可以使用requests模块来实现一个获取隧道代理的函数:

def get_tunnel_proxy():
    proxy_host = 'https://proxyserver.com'
    proxy_port = 3128
    tunnel_host = 'tunnelserver.com'
    tunnel_port = 8080
    proxy_type = 'http'

    # 构造代理隧道连接
    session = requests.Session()
    session.proxies = {
        'http': 'http://{}:{}/'.format(proxy_host, proxy_port),
        'https': 'http://{}:{}/'.format(proxy_host, proxy_port),
    }
    session.headers.update({'Proxy-Connection': 'Keep-Alive'})
    session.get('http://{}'.format(tunnel_host), timeout=10)

    # 验证隧道代理
    try:
        requests.get('http://httpbin.org/ip', proxies={'http': proxy_type + '://{}:{}'.format(tunnel_host, tunnel_port)}, timeout=2)
        return '{}://{}:{}'.format(proxy_type, tunnel_host, tunnel_port)
    except Exception as e:
        print('Error:', e)
        return None

在这个函数中,我们通过构造了一个代理隧道连接,并利用获取的IP地址在隧道代理服务器中建立连接来验证代理的有效性,最终返回一个构造好的隧道代理IP(示例中使用的是HTTP代理)。

使用上述方法获取代理IP的过程可以在爬虫启动时进行,例如,我们可以在Spider类中加入相应的过程:

class MySpider(scrapy.Spider):
    name = 'my_spider'
    allowed_domains = ['target_site.com']
    start_urls = ['https://www.target_site.com/']

    def start_requests(self):
        self.proxy = get_tunnel_proxy() # 获取隧道代理IP
        yield scrapy.Request(
            self.start_urls[0],
            callback=self.parse,
            meta={
                'proxy': self.proxy,
            }   
        )

    def parse(self, response):
        # 在这里解析网页内容
        pass

在这个Spider中,我们重载了start_requests()函数,通过get_tunnel_proxy()方法获取代理IP,并将其设置到请求的meta中。这样,后续的请求都会通过获取的隧道代理IP来发起连接。

以上就是使用隧道代理来爬取网站的完整示例,更多的代理方式可以参考文献中提供的相关链接。

参考文献

  1. Scrapy官方文档中的代理设置
  2. scrapy-proxy-pool: 一款Scrapy代理池的扩展
  3. Python爬虫使用代理池
  4. 隧道代理介绍

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python爬虫框架scrapy代理中间件掌握学习教程 - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • Python 垃圾回收机制详解

    Python 垃圾回收机制详解 概述 Python 是一种解释型语言,在执行代码时会自动进行内存管理,这种内存管理的过程主要包括内存分配和释放两个过程。Python 引入了垃圾回收机制(Garbage Collection Mechanism),其主要目的是在程序运行过程中,自动回收不再使用的内存。 垃圾回收机制 Python 的垃圾回收机制主要通过引用计数…

    python 2023年6月3日
    00
  • Python入门篇之正则表达式

    Python入门篇之正则表达式 正则表达式是一种强大的文本处理工具,它可以用来完成各种复杂的文本匹配操作。本篇教程将介绍Python中如何使用正则表达式进行文本匹配。 基本语法 正则表达式由各种特殊字符和普通字符组成,它们可以被组合成一些模式,用于匹配目标字符串中的文本。 以下是一些常用的正则表达式特殊字符: . 匹配任意一个字符 + 匹配一个或多个前一个字…

    python 2023年5月13日
    00
  • Python实现的将文件每一列写入列表功能示例【测试可用】

    下面为你详细讲解Python实现的将文件每一列写入列表功能示例。 需求说明 我们需要读取文件中的每一列数据,并将每一列的数据写入对应的列表中。 实现步骤 根据需求,我们需要按照以下步骤来实现将文件每一列写入列表的功能。 步骤一:读取文件数据 使用Python内置的open()方法打开文件,并使用readlines()方法读取文件数据,并保存在一个列表中。 w…

    python 2023年6月3日
    00
  • Python Matplotlib绘制动图平滑曲线

    下面我详细讲解一下Python Matplotlib绘制动图平滑曲线的完整攻略。 导入必要的库 我们需要导入两个库,一个是Matplotlib库,另一个是NumPy库。 import matplotlib.pyplot as plt import numpy as np 定义曲线函数 我们需要定义一条曲线函数来产生曲线数据。这里我们选用的是sin函数,函数表…

    python 2023年5月18日
    00
  • Python脚本实现DNSPod DNS动态解析域名

    下面是Python脚本实现DNSPod DNS动态解析域名的完整攻略: 步骤1:在DNSPod后台进行API Token申请 首先,需要在DNSPod的后台进行API Token的申请,具体的流程如下:1. 登录DNSPod官网并进入 控制台 – 用户中心 – 安全设置 – API Token 中;2. 点击“API Token管理”,进行token的申请;…

    python 2023年6月3日
    00
  • Python迭代器的实现原理

    Python迭代器的实现原理 什么是Python迭代器? 在Python中,迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从序列的第一个元素开始访问,直到所有元素被访问完毕,完成迭代。 Python中,可迭代的对象有以下几类: 序列类型,如字符串、列表、元组、字典等; 非序列类型,如集合、生成器等。 所有可迭代的对象都可以通过…

    python 2023年5月19日
    00
  • 玩转Win XP系统内置语音输入软件

    玩转Win XP系统内置语音输入软件攻略 Win XP系统内置了语音输入软件,可以帮助用户实现语音输入文字。下面我们来详细讲解如何玩转Win XP系统内置语音输入软件。 步骤一:打开语音输入软件 依次点击“开始”菜单 -> “所有程序” -> “附件” -> “辅助工具” -> “语音识别引擎”,即可打开语音输入软件。 步骤二:设置语…

    python 2023年6月5日
    00
  • python实现简单通讯录管理系统

    Python实现简单通讯录管理系统——完整攻略 前言 为了方便大家开发数据应用,本文以Python实现一个简单的通讯录管理系统为例,来讲解如何开发一个基本的数据管理系统。同时,为了更好的展示具体操作,本文使用 pandas 库和 SQLite 数据库来实现具体功能。读者可以根据自己的需求使用其他工具或库来实现同样的功能。 步骤一:准备开发环境 在开始开发大型…

    python 2023年5月30日
    00
合作推广
合作推广
分享本页
返回顶部