使用 Playwright 封装具备反爬对抗能力的网页爬虫,核心在于隐藏浏览器自动化特征。该方案已在多个中等反爬网站(如电商、新闻站)验证有效,能绕过大多数基于 navigator.webdriver、chrome 对象、permissions 等的检测。
核心反爬策略
要实现真正的'隐身',我们需要在启动浏览器时注入一系列伪装参数:
- 移除
navigator.webdriver标志:这是最基础的指纹,必须设为undefined。 - 注入真实 User-Agent 和 Accept-Language:避免默认头信息暴露机器身份。
- 禁用
chrome对象中的自动化属性:特别是cdc_开头的字段,这些是 Puppeteer/Playwright 的典型痕迹。 - 设置合理的 viewport、设备比例、语言:模拟真实物理设备的屏幕参数。
- 启用 JavaScript 但模拟人类行为:必要时加入随机延迟,避免请求过于规律。
- 使用非 headless 模式或伪装 headless:推荐后者,既节省资源又降低被识别风险。
注意事项
即使隐藏了特征,高频访问依然会被封禁。建议添加随机延时,不要试图用脚本暴力破解所有防护。此外,IP 代理池的配合往往比单纯的技术伪装更有效。
完整代码实现
下面是一个可直接复用的 Python 封装示例。我们重点处理上下文欺骗,确保返回原始 HTML 内容。
from playwright.sync_api import sync_playwright
import random
import time
def fetch_html(url, headers=None):
"""
使用 Playwright 获取网页内容,并隐藏自动化特征
:param url: 目标网址
:param headers: 自定义请求头
:return: 页面 HTML 字符串
"""
with sync_playwright() as p:
# 启动浏览器,禁用部分自动化检测
browser = p.chromium.launch(
headless=True,
args=[
'--disable-blink-features=AutomationControlled',
'--no-sandbox',
'--disable-dev-shm-usage'
]
)
context = browser.new_context(
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',
viewport={'width': 1920, 'height': 1080},
locale='zh-CN',
permissions=['geolocation']
)
page = context.new_page()
# 注入脚本以修改 navigator.webdriver 等属性
page.add_init_script('''
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
});
// 模拟真实的 chrome 对象结构
const originalGetter = Object.getOwnPropertyDescriptor(window, 'chrome');
Object.defineProperty(window, 'chrome', {
...originalGetter,
value: { runtime: {}, cdc_: undefined }
});
''')
try:
response = page.goto(url, wait_until='networkidle', timeout=30000)
if response and response.ok:
html = page.content()
return html
else:
print(f'Failed to load: {url}')
return None
except Exception as e:
print(f'Error occurred: {e}')
return None
finally:
browser.close()
# 使用示例
if __name__ == '__main__':
target_url = 'https://example.com'
content = fetch_html(target_url)
if content:
print('抓取成功,长度:', len(content))
# 这里可以添加随机延时,模拟人类阅读
time.sleep(random.uniform(1, 3))
调试与优化
实际运行中可能会遇到验证码或更复杂的 JS 挑战。如果遇到这种情况,可以尝试调整 args 参数,或者引入更高级的指纹伪造库。另外,记得定期更新 User-Agent 列表,因为浏览器的版本迭代很快,过时的 UA 反而容易暴露。
