
技术环境与问题背景
在爬取电商平台商品数据时,开发者使用 Python 3.9 + requests 2.26.0 环境,却频繁遭遇请求被拒绝问题,导致数据采集中断。
核心环境配置:Python 3.9 搭配 requests 2.26.0 库,目标场景为电商平台商品信息爬取。
爬虫被拒现象与特征分析
爬虫被拒常表现为特定状态码与响应头,如并发超 5 次 / 分钟时返回 429 状态码,含 'Retry-After: 60' 字段。主要特征分三类:IP 封禁(超时无响应)、UA 拦截(403 拒绝非浏览器标识)、Cookie 验证失败(302 重定向登录页)。
多纬度排查过程与关键发现
初始请求失败现象
初始请求失败多因基础配置缺失。简化代码示例:
python
import requests
# 初始错误代码(缺失关键配置)
url = "https://target-website.com/products"
response = requests.get(url) # 未设置请求头、代理等
print(response.status_code) # 频繁返回403/429
关键缺失:未设置 Referer、使用默认 Python UA、无频率控制。
分层验证与定位关键拦截点
分层验证需用 Burp Suite 抓包对比浏览器请求,结合代理池切换 IP 测试。关键发现:
UA 拦截验证:更换为 Chrome UA 后,403 错误率下降 40%
IP 封禁规律:当 IP 更换频率≥3 分钟 / 次时,请求成功率提升至 85%
Cookie 必要性:未携带目标站 Cookie 时,302 重定向概率增加 65%
核心方法:通过抓包工具对比浏览器与爬虫请求差异,搭配代理池动态测试IP策略,用数据验证拦截机制。
分层解决方案与代码实现
请求头与身份伪装优化
完整请求头配置代码:
python
from faker import Faker
import random
def generate_headers():
fake = Faker()
headers = {
"User-Agent": fake.user_agent(), # 随机生成浏览器UA
"Referer": "https://target-website.com/", # 与目标URL同源
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive"
}
return headers
# 使用示例
headers = generate_headers()
response = requests.get(url, headers=headers)
关键说明
:Referer 需与目标 URL 同源防跨域检测;使用 faker 库定期更新 UA 池,避免固定值被识别。
代理池构建与智能调度
代理池核心实现(含可用性检测):
python
import requests
from concurrent.futures import ThreadPoolExecutor
class ProxyPool:
def __init__(self, proxy_list, timeout=3):
self.proxy_list = proxy_list
self.timeout = timeout
self.valid_proxies = []
def check_proxy(self, proxy):
"""验证代理可用性"""
try:
test_url = "https://httpbin.org/ip"
response = requests.get(test_url, proxies={"http": proxy, "https": proxy}, timeout=self.timeout)
return proxy if response.status_code == 200 else None
except:
return None
def refresh_proxies(self):
"""多线程检测代理池"""
with ThreadPoolExecutor(max_workers=10) as executor:
results = executor.map(self.check_proxy, self.proxy_list)
self.valid_proxies = [p for p in results if p]
return self.valid_proxies

# 使用事例
proxy_pool = ProxyPool(["http://ip1:port", "http://ip2:port"])
valid_proxies = proxy_pool.refresh_proxies() # 过滤响应时间>3秒的IP
集成 Scrapy 配置:在 settings.py 中设置DOWNLOADER_MIDDLEWARES使用代理池。
行为模拟与频率控制
带随机延迟的请求控制代码:
python
import time
import random
def smart_request(url, headers, proxy_pool):
# 随机延迟(1-3秒)模拟真人操作间隔
time.sleep(random.uniform(1, 3))
# 随机选择代理
proxy = random.choice(proxy_pool.valid_proxies) if proxy_pool.valid_proxies else None
# 带重试机制的请求
for _ in range(3):
try:
response = requests.get(url, headers=headers, proxies={"http": proxy, "https": proxy})
if response.status_code in [200, 201]:
return response
elif response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 60))
time.sleep(retry_after) # 遵循服务器重试指令
except Exception as e:
print(f"请求失败:{e}")
time.sleep(5) # 异常后延迟重试
return None
避坑总结与经验提炼
避坑要点:
禁用免费代理池固定IP段:曾因使用某免费代理的共享IP段,导致全量请求被集体封禁(200+IP同时失效)
动态指纹更新:每季度需更新UA池和请求头模板,应对目标站指纹库升级
分布式爬取注意事项:多节点部署时需保证IP段分散,避免同一C段IP密集请求
法律合规底线:严格遵守robots协议,关键数据爬取前获取目标站授权
持续优化建议:建立请求成功率监控看板,当成功率低于阈值时自动触发指纹 / 代理策略更新。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。