← 返回博客

2024年Scrapling、Botasaurus和nodriver的代理设置:对抗反机器人技术

我们讨论在新的爬虫框架中设置代理——Scrapling、Botasaurus 和 nodriver。代码、轮换示例、选择 IP 以绕过防止机器人保护的建议。

📅2026年10月21日

经典的Selenium和Puppeteer组合越来越多地被Cloudflare,DataDome和PerimeterX等反机器人系统所阻碍。 新的框架 - Scrapling,Botasaurus和nodriver应运而生,它们最初设计时就注重绕过检测。 但即使是最先进的框架,如果没有正确配置的代理也是无用的。 在本文中,我们将讨论如何在这三种工具中连接代理,哪些错误会降低效率, 以及如何根据特定的解析任务选择IP类型。

Scrapling,Botasaurus和nodriver与Selenium的区别

这三种框架的出现是因为Selenium和普通的Puppeteer变得过于容易被检测到。 反机器人系统检查数十个参数:CDP协议,navigator.webdriver,canvas渲染,事件时序 - 经典驱动几乎在每个参数中都留下了特征痕迹。

Scrapling - 一个Python库,结合了自适应HTML解析和通过基于Camoufox的StealthyFetcher模拟浏览器的能力(Camoufox是Firefox的一个分支,具有修补的指纹)。它适合需要快速解析且资源消耗最小的任务,但同时网站的保护会积极检查TLS指纹。

Botasaurus - 基于修改版Chromium的框架(undetected-chromedriver在背后),专为大规模并行抓取而设计,具有自动管理浏览器配置文件的能力,并内置支持通过第三方服务解决验证码。

nodriver - 来自同一作者的undetected-chromedriver的继任者,完全放弃了Selenium WebDriver,直接通过CDP(Chrome DevTools Protocol)工作,这消除了大量可检测的自动化伪影。

这三者的共同点是,它们在浏览器指纹级别上降低了检测,但并没有解决IP声誉的问题。 如果请求来自已经在DataDome或Cloudflare黑名单中的数据中心IP,那么无论浏览器如何修补,都无法避免验证码或403错误。

在Scrapling中设置代理

Scrapling支持在快速HTTP模式(Fetcher)和浏览器模式(StealthyFetcher)下使用代理。 对于不需要JS渲染的静态解析,代理可以直接通过请求参数传递:

from scrapling.fetchers import Fetcher

response = Fetcher.get(
    "https://example.com",
    proxy="http://user:[email protected]:9000"
)
print(response.status)

对于完整浏览器模式(Camoufox上的StealthyFetcher),代理通过一个包含服务器、用户名和密码的字典传递 - 这很重要,因为Camoufox处理代理授权的方式与普通Chromium不同:

from scrapling.fetchers import StealthyFetcher

response = StealthyFetcher.fetch(
    "https://example.com",
    proxy={
        "server": "gate.proxycove.com:9000",
        "username": "user",
        "password": "pass"
    },
    headless=True
)
print(response.status)

常见错误是将代理作为字符串整体传递到浏览器模式,就像在HTTP请求中一样。在这种情况下,Camoufox要么忽略授权,要么在连接到代理服务器时超时。 如果看到错误ERR_NO_SUPPORTED_PROXIES - 请检查字典格式是否包含单独的字段。

在Botasaurus中设置代理

Botasaurus使用装饰器@browser 来配置驱动程序,代理作为该装饰器的参数传递,或者直接传递给启动函数:

from botasaurus.browser import browser, Driver

@browser(
    proxy="http://user:[email protected]:9000"
)
def scrape_data(driver: Driver, data):
    driver.get("https://example.com")
    return driver.page_html

scrape_data()

如果需要为每个并行任务连接不同的代理(在通过Botasaurus进行大规模抓取时至关重要),最好通过数据列表动态传递代理,而不是硬编码在装饰器中:

from botasaurus.browser import browser, Driver

@browser
def scrape_with_proxy(driver: Driver, data):
    driver.config.proxy = data["proxy"]
    driver.get(data["url"])
    return driver.page_html

tasks = [
    {"url": "https://example.com/page1", "proxy": "http://user:pass@ip1:port"},
    {"url": "https://example.com/page2", "proxy": "http://user:pass@ip2:port"},
]
scrape_with_proxy(tasks)

Botasaurus通过多进程很好地并行处理任务,因此在大规模抓取时,使用具有足够IP池的代理非常重要 - 否则多个线程将争夺同一个地址,这会立即通过请求频率模式暴露自动化。

在nodriver中设置代理

nodriver通过直接连接到CDP而不使用Selenium层,因此代理通过浏览器启动参数进行配置,而不是通过单独的API。对于不需要授权的代理,一切都很简单:

import nodriver as uc
import asyncio

async def main():
    browser = await uc.start(
        browser_args=["--proxy-server=http://gate.proxycove.com:9000"]
    )
    page = await browser.get("https://example.com")
    await asyncio.sleep(3)
    browser.stop()

asyncio.run(main())

问题在于,Chromium不支持通过--proxy-server直接使用用户名/密码的代理。 对于授权代理,在nodriver中需要建立一个无授权的本地代理隧道(例如,通过px或3proxy),或者处理CDP事件Fetch.authRequired:

import nodriver as uc
import asyncio

async def main():
    browser = await uc.start(
        browser_args=["--proxy-server=http://gate.proxycove.com:9000"]
    )
    page = await browser.get("https://example.com")

    async def auth_handler(event):
        await page.send(uc.cdp.fetch.continue_with_auth(
            request_id=event.request_id,
            auth_challenge_response=uc.cdp.fetch.AuthChallengeResponse(
                response="ProvideCredentials",
                username="user",
                password="pass"
            )
        ))

    page.add_handler(uc.cdp.fetch.AuthRequired, auth_handler)
    await asyncio.sleep(5)
    browser.stop()

asyncio.run(main())

这是三个框架中最不明显的地方 - 许多开发者花费数小时试图理解为什么授权根本不起作用,而不知道CDP中的Fetch域。

代理轮换与反机器人斗争

即使是完美配置的浏览器指纹也无法拯救,如果一个IP每分钟向受保护的域发送超过50-100个请求。DataDome和Cloudflare分析来自特定地址的请求频率和操作之间的时间模式 - 过于均匀的间隔也会引起怀疑。

所有三种框架的有效轮换方案都是相同的:

  1. 使用具有自动IP轮换的网关 - 无需为每个请求编写自己的地址更换逻辑。
  2. 对于会话任务(登录,多页面导航),通过连接字符串中的sticky参数固定IP。
  3. 对于简单的静态页面解析,每个请求或每5-10个请求轮换IP。
  4. 在请求之间添加随机延迟(1-4秒) - 这降低了基于时间模式的检测。

连接字符串中的sticky会话示例,其中session-id在10分钟内保持相同的出站IP:

proxy = "http://user-session-abc123:[email protected]:9000"

对于Botasaurus,这种方案特别有用,因为在并行抓取时,每个进程可以获得其唯一的session-id,从而在不手动管理地址列表的情况下获得稳定的不同IP池。

为每个框架选择哪种类型的代理

代理类型对解析成功的影响不亚于框架选择。以下是按任务的比较:

任务 推荐的代理类型 原因
解析Cloudflare/DataDome保护的网站 居民代理 真实家庭用户的IP很少被反机器人黑名单列入
无严格保护的大规模解析 数据中心代理 在大请求量下速度更快,成本更低
在移动网站上模拟真实用户 移动代理 电信运营商的CGNAT地址在反机器人系统中具有最高的信任度

对于Scrapling在StealthyFetcher模式下,居民代理效果最佳,因为Camoufox已经解决了浏览器指纹的问题 - 只需确保IP不被发现。对于Botasaurus,在大规模并行抓取中,数据中心代理通常在速度/价格比方面是最佳选择,前提是目标网站不使用DataDome级别的高级保护。

代理与浏览器自动化结合时的常见错误

在实践中,大多数解析失败与框架本身无关,而是与代理配置不当有关。以下是最常见的错误列表:

  • Botasaurus的所有并行线程使用相同的IP。反机器人系统会看到来自同一地址的20个并发会话,并在几分钟内将其阻止。
  • 在Scrapling的浏览器模式中将代理作为字符串传递。Camoufox需要一个带有分隔字段的字典 - 否则授权将无法通过。
  • 忽略nodriver中的CDP Fetch域。没有authRequired处理程序,授权代理根本无法连接,浏览器会在加载时挂起。
  • 会话操作时缺乏轮换。在授权会话中间更换IP会立即暴露自动化 - 使用sticky会话。
  • 代理的地理位置与浏览器的语言环境不匹配。来自德国的IP带有Accept-Language: ru头部 - 这是反欺诈评分系统的经典机器人特征。
  • 即使有轮换,请求频率也过于激进。IP轮换并不意味着可以在请求之间不做暂停 - 行为模式也会被分析。

在通过浏览器模式使用代理时,单独检查DNS泄漏非常重要 - 有时浏览器通过系统DNS解析域,而不是通过代理隧道,这会导致请求IP和解析IP之间的不同步,容易被保护系统检测到。

结论

Scrapling,Botasaurus和nodriver在浏览器指纹级别上解决检测问题的能力远超经典的Selenium,但它们都没有减少高质量代理的重要性。正确配置授权(尤其是在nodriver中通过CDP),合理的IP轮换和根据特定反机器人系统选择合适的代理类型 - 这三者是决定长期解析稳定性的关键因素。

如果您在解析具有Cloudflare或DataDome等高级保护的网站,请从 居民代理开始 - 它们因IP声誉而提供最高的成功请求比例。对于没有严格保护的大规模任务,数据中心代理在速度和成本方面仍然是最佳选择。