作为一名爬虫开发者,最头疼的往往不是数据解析,而是被网站反爬系统“拒之门外” 。本文结合我近期的一个电商数据采集项目,分享从初级到进阶的反爬应对技巧,希望对正在爬虫路上“踩坑”的朋友有所帮助。
一、为什么你的爬虫总是被封?
很多初学者写爬虫时,习惯这样写:
python
import requests
response = requests.get('https://example.com')
print(response.text)
这种“裸奔”式请求,在当下几乎寸步难行。现代网站的反爬手段通常包括:
- User-Agent 检测:识别非浏览器请求
- IP 频率限制:同一IP短时间内请求过多
- Cookie/Session 校验:检查访问轨迹是否完整
- TLS 指纹检测:JA3指纹识别请求库特征
- 验证码/行为验证:滑块、点选等
- 动态渲染:页面由JavaScript生成
二、基础防护:伪装请求头
最简单的伪装就是模拟浏览器请求头。推荐使用 fake-useragent 库:
python
from fake_useragent import UserAgent
import requests
ua = UserAgent()
headers = {
'User-Agent': ua.random,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1',
}
response = requests.get('https://example.com', headers=headers)
⚠️ 注意:fake-useragent 需要定期更新数据源,否则可能返回过时的UA。
三、进阶手段:Cookie 会话保持
很多网站需要维持会话状态,使用 requests.Session() 可以自动管理Cookie:
python
session = requests.Session()
session.headers.update(headers)
# 先访问首页获取Cookie
session.get('https://example.com')
# 再请求目标页面
response = session.get('https://example.com/data')
四、应对动态渲染:Selenium/Playwright
对于完全由JS渲染的页面,直接请求HTML拿不到数据。这时需要浏览器自动化工具:
python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless') # 无头模式
options.add_argument('--disable-blink-features=AutomationControlled')
options.add_experimental_option('excludeSwitches', ['enable-automation'])
driver = webdriver.Chrome(options=options)
driver.get('https://example.com')
html = driver.page_source
driver.quit()
⚠️ 注意:即使使用Selenium,也需要配置 excludeSwitches 来隐藏自动化特征。
五、应对IP限制:代理池的基本使用
当IP被限制时,最简单的方案是引入代理。这里展示代理的基本用法(后续文章会深入展开代理选型):
python
proxies = {
'http': 'http://your-proxy-ip:port',
'https': 'http://your-proxy-ip:port',
}
response = requests.get(url, headers=headers, proxies=proxies)
但手动维护代理列表非常低效,实践中需要构建自动化代理池,实现IP的自动获取、健康检测、轮转调度。
六、高级技巧:TLS指纹伪装
很多网站开始使用JA3指纹检测,普通的 requests 库容易被识别。如果遇到这种情况,可以尝试以下方案:
- 使用
curl_cffi库:模拟浏览器TLS指纹 - 使用
pyhttpx或直接对接浏览器内核
python
from curl_cffi import requests as cffi_requests
response = cffi_requests.get(
'https://example.com',
impersonate='chrome110' # 模拟Chrome 110的TLS指纹
)
七、避坑总结
- 不要用同一个IP高频请求:控制请求间隔(time.sleep)
- 随机化请求行为:包括请求间隔、请求顺序、点击轨迹
- 尊重 robots.txt:商业项目务必注意合规性
- 做好日志记录:记录每次请求的状态码和耗时,便于分析问题
结语
反爬与爬虫的博弈一直在演进,没有一劳永逸的方案。建议根据目标网站的反爬强度,组合使用上述技巧。下一篇文章我会深入聊聊 代理IP的选型,包括住宅代理与机房代理的实际对比,欢迎关注讨论。
如果你在爬虫实践中也遇到过有趣的反爬案例,欢迎在评论区分享交流。