首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 爬虫设备指纹实战:从原理到代码

Python 爬虫设备指纹实战:从原理到代码

原创
作者头像
用户12890632
发布于 2026-11-14 21:56:34
发布于 2026-11-14 21:56:34
170
举报

一、什么是设备指纹

设备指纹(Device Fingerprint)是网站通过 JS 收集你浏览器上百个特征后生成的唯一标识,包括:

  • 基础信息:User-Agent、屏幕分辨率、时区、语言
  • 硬件特征:Canvas 渲染差异、WebGL 显卡信息、AudioContext 音频特征
  • 环境信息:已安装字体、浏览器插件、内存/CPU 核数

换 IP、清 Cookie、开无痕模式都没用——网站照样能认出你。

二、反爬检测的三层战场

层级

检测内容

典型特征

协议层

TLS 握手(JA3/JA4)、HTTP 头顺序

requests 的 TLS 指纹与真实浏览器完全不同

环境层

Canvas/WebGL/字体/插件

navigator.webdriver=true、WebGL 显示 "Mesa OffScreen"

行为层

鼠标轨迹、滚动速度、点击间隔

直线移动、匀速滚动、固定间隔点击

三、方案一:轻量级指纹伪装(requests)

适合不需要执行 JS 的简单接口,核心是保持指纹一致性——每次请求用同一套设备信息。

代码语言:javascript
复制
import random
import hashlib
import time
import requests


class DeviceFingerprint:
    """设备指纹生成器 - 保证每次请求的指纹一致"""

    def __init__(self, device_id: str = None):
        self.device_id = device_id or self._generate_device_id()
        self.fingerprint = self._build_fingerprint()

    def _generate_device_id(self) -> str:
        base = f"{time.time()}{random.randint(1000, 9999)}"
        return hashlib.md5(base.encode()).hexdigest()[:16]

    def _build_fingerprint(self) -> dict:
        screen = random.choice(["1920x1080", "1366x768", "1440x900"])
        ua = self._random_ua()
        return {
            "device_id": self.device_id,
            "screen_resolution": screen,
            "timezone": "Asia/Shanghai",
            "language": "zh-CN",
            "platform": "Win32",
            "user_agent": ua,
        }

    @staticmethod
    def _random_ua() -> str:
        chrome_version = random.randint(120, 131)
        return (
            f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            f"AppleWebKit/537.36 (KHTML, like Gecko) "
            f"Chrome/{chrome_version}.0.0.0 Safari/537.36"
        )

    def get_headers(self) -> dict:
        fp = self.fingerprint
        return {
            "User-Agent": fp["user_agent"],
            "Accept-Language": fp["language"],
            "Accept-Encoding": "gzip, deflate, br",
            "Connection": "keep-alive",
            "Sec-Fetch-Dest": "document",
            "Sec-Fetch-Mode": "navigate",
            "Sec-Fetch-Site": "none",
            "Cache-Control": "max-age=0",
        }


class SmartCrawler:
    def __init__(self):
        self.fingerprint = DeviceFingerprint()
        self.session = requests.Session()

    def get(self, url: str):
        headers = self.fingerprint.get_headers()
        return self.session.get(url, headers=headers, timeout=10)


# 使用
crawler = SmartCrawler()
resp = crawler.get("https://example.com")
print(resp.status_code)

四、方案二:Playwright + pw-stealth-enhanced(推荐)

能执行 JS 的页面必须用浏览器自动化。pw-stealth-enhanced 可一键注入 Canvas/WebGL/Audio 噪声,Cloudflare 通过率从 12% 提升到 91%。

代码语言:javascript
复制
pip install playwright pw-stealth-enhanced
playwright install chromium
代码语言:javascript
复制
import asyncio
from playwright.async_api import async_playwright
from pw_stealth_enhanced import apply_stealth, StealthConfig


async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        context = await browser.new_context(
            viewport={"width": 1920, "height": 1080},
            user_agent=(
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                "AppleWebKit/537.36 (KHTML, like Gecko) "
                "Chrome/128.0.0.0 Safari/537.36"
            ),
        )

        config = StealthConfig(
            webgl_vendor="Google Inc. (NVIDIA)",
            webgl_renderer=(
                "ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 "
                "Direct3D11 vs_5_0 ps_5_0, D3D11)"
            ),
            locale="zh-CN",
            timezone_id="Asia/Shanghai",
            canvas_noise=True,
            audio_noise=True,
            rotate_ua=True,       # 每次新建上下文随机 UA
            rotate_viewport=True, # 随机视口
        )
        await apply_stealth(context, config=config)

        page = await context.new_page()
        await page.goto("https://bot.sannysoft.com/")
        await page.screenshot(path="stealth_test.png", full_page=True)
        await browser.close()


if __name__ == "__main__":
    asyncio.run(main())

五、方案三:Patchright / CloakBrowser(最强)

stealth 是 JS 层打补丁,Patchright 直接改驱动从 CDP 协议层面消除自动化特征;CloakBrowser 更进一步,直接改 Chromium C++ 源码编译,reCAPTCHA v3 评分可达 0.9。

代码语言:javascript
复制
# Patchright:改一行 import 即可
from patchright.sync_api import sync_playwright

with sync_playwright() as p:
    context = p.chromium.launch_persistent_context(
        user_data_dir="./browser_profile",
        channel="chrome",       # 用真实 Chrome
        headless=False,
        no_viewport=True,
        locale="zh-CN",
        timezone_id="Asia/Shanghai",
    )
    page = context.pages[0] if context.pages else context.new_page()
    page.goto("https://wlt.gzdyx.cn")
    page.wait_for_timeout(5000)
    page.screenshot(path="result.png")
    context.close()

六、关键原则

  1. 指纹必须自洽:UA 是 Windows 就别配 Mac 时区,中文语言别配美国地区。
  2. 轮换才有生命力:单套指纹用久了会被标记,生产环境必须轮换。
  3. 行为也要拟人:鼠标走贝塞尔曲线、滚动先慢后快再慢、点击有随机延迟。
  4. TLS 指纹别忽视:requests 的 JA3 与真实浏览器完全不同,高防护站点必须用浏览器方案。

️ 以上代码仅用于合法合规的数据采集和自动化测试,请遵守目标网站的 robots.txt 和服务条款。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、什么是设备指纹
  • 二、反爬检测的三层战场
  • 三、方案一:轻量级指纹伪装(requests)
  • 四、方案二:Playwright + pw-stealth-enhanced(推荐)
  • 五、方案三:Patchright / CloakBrowser(最强)
  • 六、关键原则
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档