
Scrapy爬虫代理IP怎么配置?
搞爬虫的朋友都知道,IP被封是家常便饭。用Scrapy框架写爬虫,效率是高,但目标网站一检测到你在短时间内疯狂请求,立马就把你的IP给封了,项目就得停摆。这时候,给Scrapy配上代理IP,就像给汽车换上了备胎,一个IP被封了,立马换下一个,爬虫工作完全不受影响。
配置的核心思路,就是在Scrapy发出每一个网络请求之前,给它“戴上一个面具”——也就是代理IP。这样,网站看到的是代理IP的地址,而不是你真实的服务器IP。要实现这个,主要有两种方法:一种是在每个爬虫请求里单独设置,另一种是写一个“中间件”,让Scrapy的所有请求自动走代理。对于需要大量、长期爬取的项目,使用代理IP中间件是更专业、更高效的选择The
为什么推荐使用动态住宅代理IP?
代理IP有很多种,比如数据中心IP、住宅IP。对于爬虫来说,高质量的动态住宅代理IP是首选。为什么呢?因为数据中心IP虽然便宜量又大,但很多网站都能识别出来,封禁起来毫不手软。而住宅IP来自真实的家庭宽带,是互联网上最“普通”的流量,伪装性极强,不容易被风控系统盯上。
“动态”指的是IP会按一定策略更换。你可以设置每请求几次换一个IP,或者一个IP用满多少秒后更换。这能有效模拟真实用户在不同时间、不同网络环境下访问的行为,大大降低被封的风险。在选择服务商时,要重点关注IP池的大小、覆盖的国家城市、协议的兼容性以及更换IP的灵活性。
这里推荐一下ipipgo的动态住宅代理。他们的IP池非常庞大,覆盖很多地方,并且支持按需精准定位到国家甚至城市。对于Scrapy爬虫来说,他们的HTTP(S)和SOCKS5协议支持都很完善,你可以灵活选择是按流量计费还是其他方式,并且能自定义IP是“粘性”的(一个任务期间固定用一个IP)还是“轮换”的(不断更换),非常贴合各种复杂的爬虫场景需求。
手把手编写Scrapy代理IP中间件
下面我们进入实战环节,编写一个属于自己的动态代理中间件。这个中间件会从ipipgo的代理服务中获取IP,并自动应用到Scrapy的每一个请求上。
你需要在ipipgo官网获取你的API接口。通常,他们会提供一个获取代理IP的端点(Endpoint)和你的认证信息。
第一步:创建中间件文件
在你的Scrapy项目里,找到middlewares.py文件,我们在里面添加一个新的类。
import random
import requests
from scrapy import signals
from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware
from scrapy.exceptions import NotConfigured
class IpipgoDynamicProxyMiddleware(HttpProxyMiddleware):
"""
ipipgo动态代理IP中间件
"""
def __init__(self, auth_key, api_url, mode='rotate', change_threshold=10):
你的ipipgo账户认证密钥
self.auth_key = auth_key
ipipgo提供代理IP的API地址
self.api_url = api_url
模式:'rotate'(轮换)或 'sticky'(粘性)
self.mode = mode
当模式为轮换时,每多少个请求更换一次IP
self.change_threshold = change_threshold
self.request_count = 0
self.current_proxy = None
初始获取一个代理IP
self._fetch_new_proxy()
@classmethod
def from_crawler(cls, crawler):
从settings.py中读取配置
auth_key = crawler.settings.get('IPIPGO_AUTH_KEY')
api_url = crawler.settings.get('IPIPGO_API_URL')
mode = crawler.settings.get('IPIPGO_PROXY_MODE', 'rotate')
threshold = crawler.settings.get('IPIPGO_CHANGE_THRESHOLD', 10)
if not auth_key or not api_url:
raise NotConfigured('IPIPGO_AUTH_KEY and IPIPGO_API_URL must be set in settings.')
middleware = cls(auth_key, api_url, mode, threshold)
可选:绑定一个信号,比如在每个爬虫关闭时清理资源
crawler.signals.connect(middleware.spider_closed, signal=signals.spider_closed)
return middleware
def _fetch_new_proxy(self):
"""从ipipgo API获取一个新的代理IP"""
try:
这里根据ipipgo实际的API文档构造请求
示例参数,请以官网API文档为准
params = {
'key': self.auth_key,
'mode': self.mode,
'protocol': 'http', 或 'socks5'
'country': 'us', 指定国家,可选
'city': 'new york' 指定城市,可选
}
response = requests.get(self.api_url, params=params, timeout=10)
response.raise_for_status()
proxy_data = response.json()
假设API返回格式为 {'proxy': 'http://1.2.3.4:8080'}
if proxy_data.get('proxy'):
self.current_proxy = proxy_data['proxy']
print(f" 已获取新代理IP: {self.current_proxy}")
else:
raise Exception("Failed to get proxy from API response")
except Exception as e:
print(f" 获取代理IP失败: {e}")
失败时可以重试或使用备用方案,这里简单抛出异常
raise
def process_request(self, request, spider):
检查请求是否已经设置了代理(比如某些请求不需要代理)
if 'proxy' in request.meta or not self.current_proxy:
return
判断是否需要更换IP
if self.mode == 'rotate':
self.request_count += 1
if self.request_count >= self.change_threshold:
self._fetch_new_proxy()
self.request_count = 0
将当前代理设置到请求中
request.meta['proxy'] = self.current_proxy
如果需要认证,可以在这里添加请求头(具体看ipipgo代理服务器的要求)
request.headers['Proxy-Authorization'] = basic_auth_header('username', 'password')
def spider_closed(self, spider):
"""爬虫关闭时,可以执行一些清理工作"""
print("代理中间件已关闭。")
第二步:修改Scrapy项目配置
打开你的settings.py文件,进行如下配置:
你的ipipgo账户密钥和API地址(请替换为真实值)
IPIPGO_AUTH_KEY = 'your_ipipgo_auth_key_here'
IPIPGO_API_URL = 'https://api.ipipgo.com/get_proxy' 示例地址,请参考官方文档
IPIPGO_PROXY_MODE = 'rotate' 轮换模式
IPIPGO_CHANGE_THRESHOLD = 20 每20个请求换一次IP
启用自定义的下载器中间件
DOWNLOADER_MIDDLEWARES = {
'your_project_name.middlewares.IpipgoDynamicProxyMiddleware': 543, 优先级数字,确保在默认代理中间件之前
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 400, 系统默认的,要放在后面
}
建议降低并发请求速度,更模拟真人行为
CONCURRENT_REQUESTS = 2
DOWNLOAD_DELAY = 1
第三步:在爬虫中使用
现在,你的Scrapy爬虫发出的所有请求都会自动通过ipipgo的动态代理IP了。你只需要像平常一样写爬虫规则即可,无需在每个Request里单独设置meta['proxy']The
配置与使用中的关键要点
1. 代理模式选择::
– 轮换会话(Rotating):适合大规模数据抓取,防止因单个IP请求过多被识别。在中间件里我们实现了按请求次数更换。
– 粘性会话(Sticky):适合需要保持登录状态或完成一系列连续操作的爬取任务。在ipipgo后台可以设置IP的存活时间。
2. 并发与延迟设置::不要以为有了代理IP就可以无限狂飙。即使IP一直在换,但从同一个服务器发起的、频率过高的请求行为模式本身也可能被检测。务必在settings.py中合理设置CONCURRENT_REQUESTS(并发数)和DOWNLOAD_DELAY(下载延迟)。
3. 错误处理与重试:代理IP并非100%稳定,可能会遇到连接超时、无效IP等情况。Scrapy有自己的重试中间件(RetryMiddleware)。建议在中间件的process_requestmaybeprocess_exception方法中增加逻辑,当遇到代理相关错误时,主动丢弃当前IP并获取一个新IP,然后重试请求。
4. IP地理位置定位:如果你的爬虫需要抓取特定地区的内容(比如某国的电商网站),可以利用ipipgo支持Designated country/city的功能。在调用API获取IP时,传入相应的参数即可。
常见问题与解答(QA)
Q1:配置了代理中间件,但爬虫好像没走代理,或者报连接错误?
A:检查你的IPIPGO_AUTH_KEYrespond in singingIPIPGO_API_URL是否正确。在中间件的_fetch_new_proxy方法里打印出获取到的代理地址,看是否成功。然后,在process_request方法里打印request.meta['proxy'],确认代理被设置。连接错误可能是代理IP本身不可用,可以在中间件里增加异常捕获和IP更换重试逻辑。
Q2:Scrapy爬虫应该用HTTP代理还是SOCKS5代理?
A:两者都可以,取决于你的需求和代理服务商的支持。HTTP代理更通用,配置简单。SOCKS5代理更底层,能代理各种类型的流量(包括UDP),在某些网络环境下可能更稳定。ipipgo两种协议都支持,你可以在调用API时指定protocol参数。在中间件代码中,设置request.meta['proxy']时,地址前缀要对应(http://... maybe socks5://...).
Q3:如何针对不同的爬虫或网站使用不同的代理策略?
A:你可以在中间件的process_request方法中,通过spider.name来判断是哪个爬虫,或者解析request.url来判断目标网站,从而应用不同的代理规则。例如,对A网站使用美国IP,对B网站使用轮换模式,对C网站则不使用代理。
Q4:除了ipipgo的动态住宅代理,还有其他适合爬虫的产品吗?
A:对于要求极高稳定性和长期固定IP的业务,可以考虑ipipgo的Static Residential Agents。它的IP是长期固定的,纯净度很高,适合管理多个需要固定IP的账号或进行长期的监控任务。而对于像TikTok数据抓取这类特殊场景,他们也有专门的解决方案,能提供更稳定可靠的连接。
Q5:代理IP中间件和Scrapy的并发设置冲突吗?
A:不冲突,它们是协作关系。中间件负责给每个请求“穿上”代理IP的外衣,而并发设置决定了同时有多少个“穿了外衣”的请求被发送出去。合理搭配两者才能达到最佳效果:用中间件保证IP的多样性和匿名性,用并发和延迟设置来控制请求的“节奏”,模拟人类行为。

