基于Scrapy的IP代理池搭建

本文详细介绍如何使用Python和Scrapy-Redis搭建高效稳定的爬虫代理池,通过爬取快代理网站的代理IP并验证其可用性,最终将有效代理保存至数据库,提升爬虫的稳定性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、为什么要搭建爬虫代理池

二、搭建思路

三、搭建代理池

items.py

kuai_proxy.py

middlewares.py

pipelines.py

settings.py

utils.py


一、为什么要搭建爬虫代理池

在众多的网站防爬措施中,有一种是根据ip的访问频率进行限制,即在某一时间段内,当某个ip的访问次数达到一定的阀值时,该ip就会被拉黑、在一段时间内禁止访问。

应对的方法有两种:

1. 降低爬虫的爬取频率,避免IP被限制访问,缺点显而易见:会大大降低爬取的效率。

2. 搭建一个IP代理池,使用不同的IP轮流进行爬取。

二、搭建思路

1、从代理网站(如:西刺代理、快代理、云代理、无忧代理)爬取代理IP;

2、验证代理IP的可用性(使用代理IP去请求指定URL,根据响应验证代理IP是否生效);

3、将可用的代理IP保存到数据库;

《Python爬虫代理池搭建》一文中我们已经使用Python的 requests 模块简单实现了一个IP代理池搭建,但是爬取速度较慢。由于西刺代理、快代理和云代理等网站需要爬取的IP代理列表页多达上千页,使用此种方法来爬取其实并不适合。

本文将以快代理网站的IP代理爬取为例,示例如何使用 Scrapy-Redis 来爬取代理IP。

三、搭建代理池

scrapy 项目的目录结构如下:

items.py

# -*- coding: utf-8 -*-
import re
import scrapy
from proxy_pool.settings import PROXY_URL_FORMATTER

schema_pattern = re.compile(r'http|https$', re.I)
ip_pattern = re.compile(r'^([0-9]{1,3}.){3}[0-9]{1,3}$', re.I)
port_pattern = re.compile(r'^[0-9]{2,5}$', re.I)


class ProxyPoolItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    '''
        {
            "schema": "http", # 代理的类型
            "ip": "127.0.0.1", # 代理的IP地址
            "port": "8050", # 代理的端口号
            "original":"西刺代理",
            "used_total": 11, # 代理的使用次数
            "success_times": 5, # 代理请求成功的次数
            "continuous_failed": 3, # 使用代理发送请求,连续失败的次数
            "created_time": "2018-05-02" # 代理的爬取时间
        }
    '''
    schema = scrapy.Field()
    ip = scrapy.Field()
    port = scrapy.Field()
    original = scrapy.Field()
    used_total = scrapy.Field()
    success_times = scrapy.Field()
    continuous_failed = scrapy.Field()
    created_time = scrapy.Field()

    # 检查IP代理的格式是否正确
    def _check_format(self):
        if self['schema'] is not None and self['ip'] is not None and self['port'] is not None:
            if schema_pattern.match(self['schema']) and ip_pattern.match(self['ip']) and port_pattern.match(
                    self['port']):
                return True
        return False

    # 获取IP代理的url
    def _get_url(self):
        return PROXY_URL_FORMATTER % {'schema': self['schema'], 'ip': self['ip'], 'port': self['port']}

kuai_proxy.py

# -*- coding: utf-8 -*-
import re
import time
import scrapy
from proxy_pool.utils import strip, logger
from proxy_pool.items import ProxyPoolItem


class KuaiProxySpider(scrapy.Spider):
    name = 'kuai_proxy'
    allowed_domains = ['kuaidaili.com']
    start_urls = ['https://www.kuaidaili.com/free/inha/1/', 'https://www.kuaidaili.com/free/intr/1/']

    def parse(self, response):
        logger.info('正在爬取:< ' + response.request.url + ' >')
        tr_list = response.css("div#list>table>tbody tr")
        for tr in tr_list:
            ip = tr.css("td[data-title='IP']::text").get()
            port = tr.css("td[data-title='PORT']::text").get()
            schema = tr.css("td[data-title='类型']::text").get()
            if schema.lower() == "http" or schema.lower() == "https":
                item = ProxyPoolItem()
                item['schema'] = strip(schema).lower()
                item['ip'] = strip(ip)
                item['port'] = strip(port)
                item['original'] = '快代理'
                item['created_time'] = time.strftime('%Y-%m-%d', time.localtime(time.time()))
                if item._check_format():
                    yield item
        next_page = response.xpath("//a[@class='active']/../following-sibling::li/a/@href").get()
        if next_page is not None:
            next_url = 'https://www.kuaidaili.com' + next_page
            yield scrapy.Request(next_url)

middlewares.py

# -*- coding: utf-8 -*-

import random
from proxy_pool.utils import logger


# 随机选择 IP 代理下载器中间件
class RandomProxyMiddleware(object):

    # 从 settings 的 PROXIES 列表中随机选择一个作为代理
    def process_request(self, request, spider):
        proxy = random.choice(spider.settings['PROXIES'])
        request.meta['proxy'] = proxy
        return None


# 随机选择 User-Agent 的下载器中间件
class RandomUserAgentMiddleware(object):
    def process_request(self, request, spider):
        # 从 settings 的 USER_AGENTS 列表中随机选择一个作为 User-Agent
        user_agent = random.choice(spider.settings['USER_AGENT_LIST'])
        request.headers['User-Agent'] = user_agent
        return None

    def process_response(self, request, response, spider):
        # 验证 User-Agent 设置是否生效
        logger.info("headers ::> User-Agent = " + str(request.headers['User-Agent'], encoding="utf8"))
        return response

pipelines.py

# -*- coding: utf-8 -*-

import json
import redis
from proxy_pool.settings import REDIS_HOST,REDIS_PORT,REDIS_PARAMS,PROXIES_UNCHECKED_LIST,PROXIES_UNCHECKED_SET

server = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT,password=REDIS_PARAMS['password'])

class ProxyPoolPipeline(object):

    # 将可用的IP代理添加到代理池队列
    def process_item(self, item, spider):
        if not self._is_existed(item):
            server.rpush(PROXIES_UNCHECKED_LIST, json.dumps(dict(item),ensure_ascii=False))

    # 检查IP代理是否已经存在
    def _is_existed(self,item):
        added = server.sadd(PROXIES_UNCHECKED_SET, item._get_url())
        return added == 0

settings.py

# -*- coding: utf-8 -*-
BOT_NAME = 'proxy_pool'

SPIDER_MODULES = ['proxy_pool.spiders']
NEWSPIDER_MODULE = 'proxy_pool.spiders'

# 保存未检验代理的Redis key
PROXIES_UNCHECKED_LIST = 'proxies:unchecked:list'

# 已经存在的未检验HTTP代理和HTTPS代理集合
PROXIES_UNCHECKED_SET = 'proxies:unchecked:set'

# 代理地址的格式化字符串
PROXY_URL_FORMATTER = '%(schema)s://%(ip)s:%(port)s'

# 通用请求头字段
DEFAULT_REQUEST_HEADERS = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
    'Connection': 'keep-alive'
}

# 请求太频繁会导致 503 ,在此设置 5 秒请求一次
DOWNLOAD_DELAY = 5  # 250 ms of delay

USER_AGENT_LIST = [
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
    "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
    "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
    "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
]

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

# Enable or disable downloader middlewares
# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
    'proxy_pool.middlewares.RandomUserAgentMiddleware': 543,
    #   'proxy_pool.middlewares.RandomProxyMiddleware': 544,
}

ITEM_PIPELINES = {
    'proxy_pool.pipelines.ProxyPoolPipeline': 300,
}

PROXIES = [
    "https://171.13.92.212:9797",
    "https://164.163.234.210:8080",
    "https://143.202.73.219:8080",
    "https://103.75.166.15:8080"
]

######################################################
##############下面是Scrapy-Redis相关配置################
######################################################

# 指定Redis的主机名和端口
REDIS_HOST = '172.16.250.238'
REDIS_PORT = 6379
REDIS_PARAMS = {'password': '123456'}

# 调度器启用Redis存储Requests队列
SCHEDULER = "scrapy_redis.scheduler.Scheduler"

# 确保所有的爬虫实例使用Redis进行重复过滤
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"

# 将Requests队列持久化到Redis,可支持暂停或重启爬虫
SCHEDULER_PERSIST = True

# Requests的调度策略,默认优先级队列
SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.PriorityQueue'

utils.py

# -*- coding: utf-8 -*-
import logging

# 设置日志输出格式
logging.basicConfig(level=logging.INFO,
                    format='[%(asctime)-15s] [%(levelname)8s] [%(name)10s ] - %(message)s (%(filename)s:%(lineno)s)',
                    datefmt='%Y-%m-%d %T'
                    )
logger = logging.getLogger(__name__)

# Truncate header and tailer blanks
def strip(data):
    if data is not None:
        return data.strip()
    return data

 

<think>好的,用户问的是DeepSeek-R1满血普通区别。我需要先确认这两个本的具体信息。可能涉及硬件配置、性能参数、功能特性或者应用场景的不同。 首先,我应该回想一下之前学过的关于DeepSeek-R1的知识。根据记忆,DeepSeek-R1是深度求索公司开发的智能助手,可能像其他AI模型一样,有不同本,比如基础增强满血可能指的是性能更强的本,可能在模型规模、响应速度、多轮对话能力、支持的功能等方面有提升。 接下来要考虑用户可能的背景。用户可能是普通消费者,想了解哪个本更适合自己,或者是技术人员,想了解技术差异。用户的问题比较直接,可能需要简洁明了的对比,但也要确保信息准确。 需要确认是否有官方资料提到这两个本的区别。假设没有公开详细资料,可能需要基于常见的本差异来推测。比如满血可能有更大的参数数量,更好的理解能力,更高的响应速度,支持更复杂的任务,或者具备更多的定制化功能。 另外,要注意可能的命名差异,有时候“满血”可能指解锁了全部功能的本,而普通可能在某些方面有限制,比如处理速度、同时处理的请求数,或者API调用的限制。 还要考虑价格可用性,满血可能面向企业用户或需要更高性能的场景,而普通适合一般用户。不过如果这是内部测试本或未公开的,可能需要说明信息不足,建议查阅官方渠道。 需要确保回答准确,如果有不确定的地方,应该建议用户参考官方发布的信息,避免提供错误的内容。同时保持回答结构清晰,分点列出区别,方便用户快速理解。 最后,检查是否有遗漏的关键点,比如是否支持多语言、特定领域的优化、隐私保护措施等,这些也可能是本间的差异。但如果没有明确的信息,可能需要避免猜测,保持回答基于已知信息。 总结,应该分点列出可能的区别,包括性能、功能、应用场景、访问限制等方面,同时提醒用户以官方信息为准,确保回答的可靠性实用性。</think>DeepSeek-R1是深度求索公司(DeepSeek)开发的智能助手,其不同本通常会在性能、功能或适用场景上有所区别。关于**DeepSeek-R1满血**与**DeepSeek-R1**的区别,以下是一些可能的差异方向(基于常见的本迭代逻辑推测,具体以官方信息为准): --- ### 1. **性能与模型规模** - **满血**:可能采用更大规模的模型参数,拥有更强的语义理解、推理能力生成质量,尤其在复杂任务(如长文本生成、多轮对话、逻辑推理)中表现更优。 - **标准**:可能在模型规模或计算资源上有所精简,适合轻量级任务或对响应速度要求较高的场景。 --- ### 2. **功能特性** - **满血**:可能支持更多高级功能,例如: - 更长的上下文记忆(处理更长对话历史)。 - 支持插件或外部工具调用(如联网搜索、数据分析等)。 - 多模态能力(图文混合处理)。 - **标准**:功能相对基础,专注于通用对话常见任务。 --- ### 3. **响应速度与资源占用** - **满血**:可能因模型复杂度更高,对算力需求较大,响应速度略慢,但结果更精准。 - **标准**:可能优化了推理效率,响应更快,适合实时交互场景。 --- ### 4. **应用场景** - **满血**:面向企业级用户或复杂需求,如专业咨询、代码开发、数据分析等。 - **标准**:适合个人用户的日常问答、简单创作等场景。 --- ### 5. **访问权限与成本** - **满血**:可能需要通过API付费订阅或专属授权访问,成本较高。 - **标准**:可能免费开放或提供基础限次API,成本更低。 --- ### 注意事项 - 具体差异需以**官方发布信息**为准,建议通过DeepSeek官网或技术文档获取最新本说明。 - 本命名可能因公司策略调整而变化(例如“满血”可能指完全体模型,而标准是轻量化部署)。 如果需要进一步确认细节,可关注深度求索公司的官方公告或联系其技术支持。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值