本文目录导读:

- 案例一:基础请求头伪装(防User-Agent检测)
- 案例二:IP代理池(防IP封禁)
- 案例三:请求频率控制(防触发限流)
- 案例四:Cookie与Session保持(防登录失效)
- 案例五:JavaScript渲染页面处理(防动态内容检测)
- 案例六:请求头完整伪装(防指纹识别)
- 案例七:应对验证码(CAPTCHA)
- 实战综合案例:采集电商商品信息
- 核心原则总结
Python爬虫在采集数据时,确实容易遭遇目标网站的反爬机制,下面整理了一些真实且实用的防封案例,涵盖从入门到进阶的多种规避策略,希望对你有帮助。
案例一:基础请求头伪装(防User-Agent检测)
问题场景:Python的requests库默认User-Agent是python-requests/2.x.x,很容易被识别。
解决方案:随机切换主流浏览器User-Agent。
import requests
from fake_useragent import UserAgent
# 方式1:使用fake_useragent库(推荐)
ua = UserAgent()
headers = {'User-Agent': ua.random}
# 方式2:手动构建UA池
user_agent_list = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ...',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ...',
# ... 更多UA
]
headers = {'User-Agent': random.choice(user_agent_list)}
response = requests.get(url, headers=headers)
案例二:IP代理池(防IP封禁)
问题场景:同一IP短时间内大量请求,触发频率限制或IP黑名单。
解决方案:构建动态IP代理池,每次请求随机切换IP。
import requests
import random
# 代理池示例(可以从免费/付费代理源获取)
proxy_pool = [
'http://123.123.123.123:8080',
'http://111.111.111.111:3128',
# 更多代理
]
def get_random_proxy():
proxy = random.choice(proxy_pool)
return {'http': proxy, 'https': proxy}
response = requests.get(url, headers=headers, proxies=get_random_proxy(), timeout=5)
进阶技巧:
- 使用付费代理服务(如快代理、芝麻代理)稳定性更高
- 动态验证代理可用性后再使用
- 对HTTP/HTTPS分别配置不同代理
案例三:请求频率控制(防触发限流)
问题场景:请求过于频繁,触发网站的反爬机制(如验证码、返回假数据、503状态码)。
解决方案:模拟人类行为,随机延迟、随机点击间隔。
import time
import random
def crawl_with_delay(url):
# 随机延迟 1~3 秒
delay = random.uniform(1, 3)
time.sleep(delay)
response = requests.get(url, headers=headers)
return response
# 更高级:根据服务器响应时间自适应延迟
def adaptive_delay(response):
# 如果服务器响应慢,放慢速度
if response.elapsed.total_seconds() > 2:
time.sleep(random.uniform(3, 5))
else:
time.sleep(random.uniform(1, 2))
案例四:Cookie与Session保持(防登录失效)
问题场景:需要登录状态的页面,或者网站通过Cookie跟踪会话行为。
解决方案:使用requests.Session维持会话,模拟完整用户行为。
session = requests.Session()
# 先获取登录页面(模拟真实浏览器访问顺序)
login_page = session.get('https://example.com/login', headers=headers)
# 解析验证码、填充表单等
# session.post('https://example.com/login', data=login_data)
# 后续所有请求都使用同一个session
response = session.get('https://example.com/protected/data', headers=headers)
案例五:JavaScript渲染页面处理(防动态内容检测)
问题场景:数据通过JavaScript动态加载,直接请求HTML拿不到数据。
解决方案:使用Selenium/Playwright模拟真实浏览器,或直接分析API接口。
# 方式1:使用Playwright(推荐,比Selenium轻量)
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...',
viewport={'width': 1280, 'height': 720}
)
page = context.new_page()
page.goto('https://example.com')
# 等待动态内容加载
page.wait_for_selector('.dynamic-content')
content = page.content()
# 方式2:直接抓API接口(更高效)
# 通过浏览器开发者工具Network面板找到真实API接口
api_url = 'https://api.example.com/v1/data?page=1'
response = requests.get(api_url, headers={
'Referer': 'https://example.com', # 重要:带上来源
'User-Agent': ua.random
})
案例六:请求头完整伪装(防指纹识别)
问题场景:网站通过检测请求头的顺序、缺失字段等指纹特征识别爬虫。
解决方案:模拟浏览器完整的请求头,包括Accept、Accept-Language、Accept-Encoding、Connection、Referer等。
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Referer': 'https://www.baidu.com/', # 模拟从搜索引擎进入
'DNT': '1', # Do Not Track
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'none',
'Sec-Fetch-User': '?1',
}
案例七:应对验证码(CAPTCHA)
问题场景:频繁请求触发验证码,导致无法继续采集。
解决方案:按优先级尝试以下几种方法:
- 降低频率:最根本的解决方法,让行为更像人类
- 使用OCR:简单验证码可用
pytesseract识别 - 打码平台:付费服务如超级鹰、打码兔
- 机器学习:针对特定验证码训练识别模型
- 模拟点击:对滑块验证码使用
selenium模拟滑动
# 伪代码:使用打码平台
def solve_captcha(image_data):
# 调用打码平台API
api_key = 'your_key'
result = captcha_api.recognize(image_data, api_key)
return result
实战综合案例:采集电商商品信息
import requests
import time
import random
from fake_useragent import UserAgent
from playwright.sync_api import sync_playwright
class ECommerceSpider:
def __init__(self):
self.session = requests.Session()
self.ua = UserAgent()
self.proxy_pool = [...] # 代理IP池
def get_headers(self):
return {
'User-Agent': self.ua.random,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': 'https://www.google.com/',
}
def get_proxy(self):
proxy = random.choice(self.proxy_pool)
return {'http': proxy, 'https': proxy}
def crawl_product(self, url):
# 随机延迟 2~5 秒
time.sleep(random.uniform(2, 5))
# 使用Playwright渲染动态页面
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto(url)
page.wait_for_selector('.product-price')
price = page.text_content('.product-price')
title = page.text_content('.product-title')
return {
'title': title,
'price': price,
'url': url
}
# 使用示例
spider = ECommerceSpider()
products = []
for url in product_urls:
try:
data = spider.crawl_product(url)
products.append(data)
except Exception as e:
print(f"采集失败: {url}, 错误: {e}")
time.sleep(10) # 出错后多等一会儿
核心原则总结
| 策略 | 适用场景 | 效果 |
|---|---|---|
| 请求头伪装 | 基础封IP/UA | 中等 |
| IP代理池 | 高频率采集 | 高(需搭配其他策略) |
| 延迟控制 | 几乎所有场景 | 中等(基础但重要) |
| Session保持 | 需登录/会话跟踪 | 高 |
| 浏览器渲染 | JavaScript动态页面 | 极高但速度慢 |
| 请求头完整性 | 指纹识别严格 | 高 |
| 验证码处理 | 高封禁门槛 | 视技术手段而定 |
重要提醒:请务必遵守目标网站的
robots.txt协议和相关法律法规,合理控制采集频率,不抓取敏感数据,尊重网站的合法权益,爬虫技术应只用于合法合规的数据收集场景。