一、 引言:为何我们的爬虫会被“封杀”?
当我们兴致勃勃地编写好一个爬虫脚本,初期运行顺畅,但很快便会遭遇 403 Forbidden、429 Too Many Requests,甚至IP被直接封禁的窘境。这背后,是网站防御系统对我们发起的挑战:
频率特征:同一IP在短时间内发起大量请求,行为明显异于正常人类用户。
指纹特征:使用默认的requests或urllib库的User-Agent,服务器可轻易识别出这是爬虫程序。
行为模式:缺乏有效的Cookie、Referer等头部信息,访问路径单一。
要解决这些问题,我们的核心策略是:让爬虫尽可能地模拟真实用户的访问行为。这其中的两大基石便是IP代理与请求头伪装。
二、 核心技术一:请求头伪装 - 成为“浏览器”而非“脚本”
请求头是HTTP请求的“身份证”,它向服务器传递了客户端的详细信息。我们的首要任务就是为爬虫伪造一张合法的“身份证”。
1. 基础伪装:设置User-Agent
User-Agent是标识浏览器类型和版本的最关键字段。
2. 高级伪装:构建完整的浏览器指纹
一个真实的浏览器请求会携带数十个头部字段。仅设置User-Agent是远远不够的。
关键点:Referer字段尤为重要,它告诉服务器当前请求是从哪个页面链接过来的,模拟用户的连续浏览行为。
三、 核心技术二:IP代理 - 打造“千面”爬虫
即使请求头伪装得再好,来自单一IP的高频请求依然会暴露。使用IP代理池,让请求来自全球各地的不同机器,是突破IP封锁的根本手段。
1. 获取代理IP
代理IP的来源主要有以下几类:
免费代理:缺点是稳定性差、可用率低,仅适用于测试。
付费代理服务:提供高匿、稳定的HTTP/HTTPS/SOCKS5代理,通常通过API接口获取IP列表,是商业项目的首选。
自建代理池:通过扫描公网或云服务器自建,技术门槛和成本较高,但控制力最强。
2. 构建IP代理池管理器
我们将创建一个类来管理代理IP,包括获取、验证、轮换和剔除失效IP。
3. 集成IP代理与请求头伪装
现在,我们将两大技术整合到番茄小说爬虫的核心请求函数中。
import requests
else:
print("请求可能被反爬系统拦截,检测到验证码页面")
else:
print(f"请求失败,状态码: {response.status_code}")
except (requests.exceptions.ProxyError,
requests.exceptions.ConnectTimeout,
requests.exceptions.ReadTimeout,
requests.exceptions.ConnectionError) as e:
print(f"第 {attempt + 1} 次请求失败: {e}")
if attempt < max_retries - 1:
wait_time = 2 ** attempt # 指数退避策略
print(f"等待 {wait_time} 秒后重试...")
time.sleep(wait_time)
continue
else:
print("所有重试均失败")
raise e
# 如果不是网络错误,但请求被拦截,也进行重试
if attempt < max_retries - 1:
wait_time = 2 ** attempt
print(f"请求可能被拦截,等待 {wait_time} 秒后重试...")
time.sleep(wait_time)
return None
# 为session绑定新的方法
session.robust_request = _make_request
return session
# 主爬虫函数
def crawl_fanqie_novel(book_id):
"""爬取番茄小说内容"""
# 初始化代理池管理器
proxy_manager = ProxyPoolManager()
# 创建稳健的Session
session = create_robust_session(proxy_manager)
# 构造目标URL
url = f'https://fanqienovel.com/reader/{book_id}'
print(f"开始爬取: {url}")
try:
# 使用我们自定义的稳健请求方法
response = session.robust_request(url)
if response and response.status_code == 200:
# 此处接续你的HTML解析逻辑
print("成功获取页面内容!")
# 可以在这里添加内容解析代码
# soup = BeautifulSoup(response.text, 'html.parser')
# ... 解析逻辑
return response.text
else:
print("爬取失败,请检查网络或反爬策略。")
return None
except Exception as e:
print(f"爬虫执行过程中发生错误: {e}")
return None
# 使用示例
if __name__ == "__main__":
# 测试爬虫
book_id = '123456789012345'
result = crawl_fanqie_novel(book_id)
if result:
print("爬取成功!")
# 处理爬取到的内容
else:
print("爬取失败!")
四、 高级策略与最佳实践
请求频率控制:在关键请求之间使用time.sleep(random.uniform(1, 3)),模拟人类阅读的随机间隔。
会话保持:对于需要登录或保持状态的任务,使用requests.Session()对象,它会自动处理Cookies。
CAPTCHA处理:当遭遇验证码时,可以:a) 使用第三方打码平台;b) 临时切换更高匿名度的代理;c) 暂停爬虫一段时间。
监控与日志:记录每个请求使用的代理、耗时、状态码,便于分析代理质量和网站反爬策略的变化。
五、 总结
通过系统地集成请求头伪装与IP代理池,我们的番茄小说爬虫成功地从一只容易被拍死的“苍蝇”,进化成了一个拥有无数伪装身份的“特工”。这不仅是技术的叠加,更是一种工程思维的体现:将爬虫系统视为一个需要持续对抗、适应和演化的有机体。
红包分享
钱包管理

