Scrapy Proxy IP Pool
这是一个Scrapy中间件,用于管理代理IP池。
- 🥳支持Redis:支持使用Redis的IP代理池(也可本地List作为代理池)
- 🥵最大限度榨干每个IP: 只有请求为指定异常or状态码(被封)时才会更换IP
- 🤌简单配置: ez三步即可使用
如果你不知道如何写"代理IP池"可以花几分钟看下(<10min)然后可以自己写,当然也可以用我写的现成代理池
安装
使用以下命令安装:
pip install scrapy_proxy_ip_pool
基本使用
STEP1:在setting.py中添加该中间件
- 要求❗: 这里的权值一定要大于
RetryMiddleware(重试中间件默认550)
PROXY_POOL_SIZE = 1 # 代理池的大小(有封ip的网站建议开大一点)
DOWNLOADER_MIDDLEWARES = {
'scrapy_proxy_ip_pool.proxy_pool_downloader_middleware.ProxyPoolDownloaderMiddleware': 551,
}
STEP2:在你的spider中必须要编写def get_proxy_ip(self):->str方法
- 要求❗:名字只能是这个,返回值是一个代理IP.
- 说明: 代理池中间件会读取这个方法,从而获取代理IP地址.
import requests
import scrapy
class IpSpider(scrapy.Spider):
name = "ip"
REDIS_KEY = name
def parse(self, response, **kwargs):
pass
# 示例
def get_proxy_ip(self):
api_url = "你请求付费代理的地址"
proxy_ip = requests.get(api_url).text
username = "你的代理用户名"
password = "你的代理密码"
return f"http://{username}:{password}@{proxy_ip}/" # 一次只需要返回一个ip
其他配置
一. 使用Redis作为 代理池
settings.py中配置如下内容:
PROXY_POOL_ENABLED = 'True' # 使用Redis进行代理池的构建(默认为False)
REDIS_URL = "redis://127.0.0.1:6379/0"
spider中添加REDIS_KEY变量指明存储在Redis中使用的键
import scrapy
class IpSpider(scrapy.Spider):
name = "ip"
REDIS_KEY = name # 最终为 REDIS_KEY+":proxy_pool"
...
二. 指定异常和状态码
settings.py中配置如下内容- 说明: 如果遇到了这些异常, 就会更新IP; 如下默认配置的是常见可能被封异常和状态码
- 注意❗:这里依据网址而定, 如果不确定, 两个可以设置为空列表,后续根据报错改
# 如下列举了常见的被封禁ip(或ip不可用)时的异常或状态码, 用户可以根据目标网站的情况在settings.py中自行配置
NEED_UPDATE_PROXY_EXCEPTIONS = [
'twisted.internet.defer.TimeoutError', # 请求超时未响应,可能目标服务器检测到代理IP异常导致故意延迟不响应
'twisted.internet.error.TimeoutError', # 底层网络连接超时,可能代理服务器IP被目标网站封锁导致无法建立连接
'twisted.internet.error.ConnectError', # 与代理服务器建立连接失败,可能代理IP已被防火墙封禁或服务器已下线
'scrapy.core.downloader.handlers.http11.TunnelError', # 代理服务器要求身份验证或目标网站封禁该代理IP,导致无法建立HTTPS隧道连接
]
NEED_UPDATE_PROXY_CODES = [
503, # 服务不可用,服务器可能正在主动拒绝来自该代理IP的请求(反爬机制触发)
407, # 代理身份验证失败,或代理服务提供商已封禁当前IP的访问权限
403, # 服务器明确拒绝访问,通常表示当前代理IP已被加入黑名单
429, # 请求频率超限,目标网站针对该代理IP实施了速率限制
]
关键代码
一. 更新IP
- ⏱什么时候会被调用:只有出现
NEED_UPDATE_PROXY_EXCEPTIONS或NEED_UPDATE_PROXY_CODES中的异常或状态码,该方法才会被调用
# 伪代码
def update_proxy(self, request: Request) -> Request:
last_ip = 本次(有问题)
请求的代理ip
if last_ip in 代理池:
在代理池中更换该(有问题)
的ip
request.meta['proxy'] = 新ip
return request
def update_proxy(self, request: Request) -> Request:
"""
使用"乐观锁"思想,更新过时IP,并返回携带新IP的request
:param request: 未成功的网络请求
:return: 返回携带新IP的request
"""
# 解决request.meta['proxy']鉴权丢失问题
last_proxy = request.meta['proxy'].split("//")[1]
temp_proxy_list = self.client.smembers(self.redis_key) if self.proxy_pool_enabled else self.proxy_pool
need_update = any(last_proxy in ip for ip in temp_proxy_list) # 存在=>需要替换
# 当前需要获取新的ip
if need_update:
# 替换"代理池"中的IP
if self.proxy_pool_enabled: # Redis
self.client.srem(self.redis_key, last_proxy)
self.client.sadd(self.redis_key, self.get_proxy_with_logging())
else: # 本地
self.proxy_pool.remove(last_proxy)
self.proxy_pool.append(self.get_proxy_with_logging())
# 更换代理IP进行请求
request.meta['proxy'] = self.get_proxy_from_pool()
request.dont_filter = True # 防止被过滤!!!
return request
Version
1.0.2:【2025年2月4日】- fix bug in
1.0.1
- fix bug in
1.0.1:【2025年2月4日】- 修改
1.0.0中的Bug(①修改包名,②完善README.md文档) - 推送项目到Pypi,用户可以使用pip进行下载
- 首次推送项目到Gitee:
- 修改
1.0.0:【2025年2月3日】- 首次推送至GitHub,能够实现代理池功能
Metadata
Release files for scrapy-proxy-ip-pool 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scrapy_proxy_ip_pool-1.0.2.tar.gz | 6.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scrapy_proxy_ip_pool-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.8 kB
Release files / scrapy_proxy_ip_pool-1.0.2.tar.gz
| Download URL | scrapy_proxy_ip_pool-1.0.2.tar.gz |
|---|---|
| Size | 6.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4ca43e7a68a7d03f4b413deeb66ac1205f1a0a7afa2b858812d7e3a7d0292d89
|
|
BLAKE2b-256 checksum How to use checksums |
16a743f2c1a4b6878ce1a9c7e2b36fb776d2b583d1287194a52ff07c3d313901
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.16
|
Release files / scrapy_proxy_ip_pool-1.0.2-py3-none-any.whl
| Download URL | scrapy_proxy_ip_pool-1.0.2-py3-none-any.whl |
|---|---|
| Size | 7.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
44a6bb061d91199a48bad9fa30e2bec82fbf5a051e7decf602fc7e260a290333
|
|
BLAKE2b-256 checksum How to use checksums |
975f3ae30f0312e5bcf0c262e603f784f1bcc2b3c8a2f64019f7691b784ad1b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.10.16
|