一、为什么要"像人一样"爬

新手脚本常出现"第一跑通、第二被封",根因是机器人流量在统计特征上与真人差异明显

  • 请求间隔高度规律(sleep(2) 方差≈0);
  • User-Agent 全程不变;
  • 页面一开就直奔元素,无滚动、无停留;
  • navigator.webdriver === true 直接暴露自动化身份。

反爬系统无需"看懂"你在干嘛,只要在流量层识别上述异常即可低成本拦截。"拟真"的本质,是让爬虫特征分布贴合正常用户,降低风控命中率。本文聚焦三板斧 + 亿牛云代理,给出可运行代码。


二、随机延时:打破规律性

固定延时是最大破绽。真人操作间隔更接近对数正态分布(多数快、偶尔停顿久),而非均匀分布。

import random, time

def human_delay(min_s=0.5, max_s=3.0):
    """对数正态随机延时,截断到合理区间。"""
    delay = random.lognormvariate(0.5, 0.6)
    delay = max(min_s, min(max_s, delay))
    time.sleep(delay)
    return delay

再按动作分级配置档位:列表滚动 0.5–1.5s、打开详情 1.5–4s、点击提交 2–5s。多层延时让节奏更自然。


三、UA 轮换:隐藏同一身份

固定 UA 等于举牌自报。维护一个经过验证的真实 UA 列表,用 CDP 注入(比 --user-agent 参数更彻底,能覆盖 navigator.userAgent 及首请求头):

import random
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

UA_POOL = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
    "(KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0",
]

options = Options()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd("Network.setUserAgentOverride",
                       {"userAgent": random.choice(UA_POOL)})

坑点:CDP 注入只对之后创建的页面生效,首次 get 前须设好。


四、行为模拟:补上最后一里路

真人会移动鼠标、滚动、逐字输入。细节显著提升拟真度:

from selenium.webdriver.common.action_chains import ActionChains

def human_type(el, text):
    for ch in text:
        el.send_keys(ch)
        time.sleep(random.uniform(0.05, 0.2))

def human_scroll(driver, total=800):
    for _ in range(0, total, 100):
        driver.execute_script("window.scrollBy(0, 100);")
        time.sleep(random.uniform(0.1, 0.4))

def human_move(driver, el):
    ActionChains(driver).move_to_element_with_offset(
        el, random.randint(-5, 5), random.randint(-5, 5)).perform()
    time.sleep(random.uniform(0.2, 0.6))

五、亿牛云代理:给爬虫换"出口 IP"

仅靠本地 IP + 拟人行为,面对频率限制 / IP 信誉库仍会被封。亿牛云(16yun)提供爬虫代理(隧道 / 私密代理),核心是给每个请求换出口 IP。其代理需用户名密码认证,而 Chrome 的 --proxy-server 不支持 URL 内嵌认证,必须用 Chrome 扩展注入。

5.1 生成带认证的代理扩展

import zipfile

def build_proxy_extension(host, port, user, pwd, path="proxy_auth.zip"):
    """生成 Chrome 代理认证扩展(亿牛云代理需账密认证)。"""
    manifest = """{"version":"1.0.0","manifest_version":2,
    "name":"ProxyAuth","permissions":["proxy","tabs","storage",
    "<all_urls>","webRequest","webRequestBlocking"],
    "background":{"scripts":["background.js"]}}"""
    bg = """
    var cfg={mode:"fixed_servers",rules:{singleProxy:{
        scheme:"http",host:"%s",port:%s},bypassList:["localhost"]}};
    chrome.proxy.settings.set({value:cfg,scope:"regular"},()=>{});
    chrome.webRequest.onAuthRequired.addListener(
        d=>({authCredentials:{username:"%s",password:"%s"}}),
        {urls:["<all_urls>"]},["blocking"]);
    """ % (host, port, user, pwd)
    with zipfile.ZipFile(path, "w") as z:
        z.writestr("manifest.json", manifest)
        z.writestr("background.js", bg)
    return path

5.2 在 Selenium 中接入亿牛云

亿牛云控制台会给出代理地址、端口、用户名、密码(隧道代理形如 t.16yun.cn:xxxx)。将其填入扩展并加载:

options = Options()
options.add_extension(build_proxy_extension(
    host="t.16yun.cn",      # 替换为亿牛云实际代理 host
    port=31111,             # 替换为实际端口
    user="YOUR_16YUN_USER", # 亿牛云账号
    pwd="YOUR_16YUN_PASS",  # 亿牛云密码
))
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(options=options)
driver.execute_cdp_cmd("Network.setUserAgentOverride",
                       {"userAgent": random.choice(UA_POOL)})

接入建议:① 用隧道代理实现自动换 IP,免去手动维护 IP 池;② 配合随机延时,避免代理资源被高频打满;③ 代理失败时用指数退避重试,别暴力重试。


六、综合实战

import random, time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

TARGET = "https://example.com/list"  # 替换为你有权抓取的地址

def crawl():
    options = Options()
    options.add_extension(build_proxy_extension("t.16yun.cn", 31111,
                        "YOUR_16YUN_USER", "YOUR_16YUN_PASS"))
    options.add_argument("--disable-blink-features=AutomationControlled")
    driver = webdriver.Chrome(options=options)
    driver.execute_cdp_cmd("Network.setUserAgentOverride",
                           {"userAgent": random.choice(UA_POOL)})
    out = []
    try:
        driver.get(TARGET)
        human_delay(1.5, 4.0)
        for _ in range(3):
            human_scroll(driver, 600)
            items = WebDriverWait(driver, 10).until(
                EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".item-title")))
            for it in items:
                human_move(driver, it)
                out.append(it.text.strip())
            human_delay(2.0, 5.0)
            driver.find_element(By.CSS_SELECTOR, ".next-page").click()
    finally:
        driver.quit()
    return out

要点:UA 走 CDP 注入 + 清 webdriver 指纹;延时用对数正态分级;滚动/移动/输入全拟人;WebDriverWait 替代裸 sleep;出口 IP 由亿牛云代理承载。


七、合规与边界

  • 拟人化只降低被识别概率,无法 100% 绕过强风控(设备指纹、行为生物特征等维度远超本文);
  • 抓取前读 robots.txt,遵守 Crawl-delay
  • 控制频率,不压垮对方服务器;仅采公开非敏感数据;
  • 商业用途务必取得授权。

小结:模拟真人 = 间隔随机 + 身份多变 + 动作有迹 + 出口 IP 干净。三板斧加亿牛云代理足以应付中低强度反爬,但合规与克制才是能长期跑下去的根本。

依赖:pip install selenium webdriver-manager。运行前替换 TARGET、选择器及亿牛云凭证,并确认目标站点允许抓取。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐