开始之前

  • Python 3.10 或更新版本,这是 Crawl4AI 的要求。
  • 较新的 Crawl4AI。旧教程会给 BrowserConfig 传一个 proxy 字符串,在 0.9.4 中仍能运行,但会打印弃用警告。
  • 服务页面上的 HOST、PORT、USERNAME 和 PASSWORD。

你的连接信息

登录控制台,打开你购买的服务。服务页面上会显示该服务的主机、端口、用户名和密码。ProxyPanda 没有一个统一的固定地址,所以每次都请从那里复制。指南中的代码使用下面这些占位符,请逐一替换成你自己的值。

HOST
该服务的代理地址,按服务页面上显示的原样填写。
PORT
要连接的端口。请和主机一起复制,因为不同服务的端口可能不同。
USERNAME
你的代理登录名。它与你登录控制台所用的邮箱是分开的。
PASSWORD
请完整复制。住宅代理在控制台中选择的选项会附加在密码末尾,凭记忆手动输入的密码会丢失这些选项。

把你用来连接的 IP 地址加入服务的白名单,就可以不用用户名和密码。这时代码里只需要 HOST 和 PORT。

示例都使用 HTTP,它可以通过加密隧道访问 https 网站。SOCKS5 同样可用:住宅代理的端口两种都接受,ISP 和数据中心代理在控制台里切换协议。

步骤

  1. 在虚拟环境中安装 Crawl4AI

    crawl4ai-setup 会下载 Playwright 需要的 Chromium,并初始化 Crawl4AI 的本地数据库。全部装在 .venv 里,不同项目的浏览器和依赖就不会互相冲突。

    terminal
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -U crawl4ai
    crawl4ai-setup
  2. 给 BrowserConfig 设置 ProxyConfig

    server 只写协议、主机和端口。username 和 password 放在单独的字段里,浏览器会用它们回应代理的登录验证。这个爬虫打开的每个页面都经过代理。

    crawl_ip.py
    import asyncio
    
    from crawl4ai import AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, ProxyConfig
    
    proxy = ProxyConfig(server="http://HOST:PORT", username="USERNAME", password="PASSWORD")
    browser_config = BrowserConfig(headless=True, proxy_config=proxy)
    
    
    async def main():
        async with AsyncWebCrawler(config=browser_config) as crawler:
            result = await crawler.arun("https://api.ipify.org?format=json", config=CrawlerRunConfig())
            print(result.success, result.status_code)
            print(result.markdown)
    
    
    asyncio.run(main())
  3. 查看返回结果

    脚本会先打印 True 200,然后是包在 markdown 代码块里的 api.ipify.org JSON。ip 的值就是代理的出口地址。

  4. 用 RoundRobinProxyStrategy 在列表中轮换

    ProxyConfig.from_string 按 HOST:PORT:USERNAME:PASSWORD 的顺序读取一行,与控制台导出的顺序相同。每次调用 arun,策略都会交出下一项,日志里每次都会打印一行 Switch proxy。page_timeout 的单位是毫秒。

    rotate.py
    import asyncio
    
    from crawl4ai import AsyncWebCrawler, CrawlerRunConfig, ProxyConfig, RoundRobinProxyStrategy
    
    with open("proxies.txt") as f:
        proxies = [ProxyConfig.from_string(line) for line in f if line.strip()]
    
    run_config = CrawlerRunConfig(
        proxy_rotation_strategy=RoundRobinProxyStrategy(proxies),
        check_robots_txt=True,
        page_timeout=60000,
    )
    
    
    async def main():
        urls = ["https://api.ipify.org?format=json"] * 6
        async with AsyncWebCrawler() as crawler:
            for url in urls:
                result = await crawler.arun(url, config=run_config)
                print(result.success, result.markdown if result.success else result.error_message)
    
    
    asyncio.run(main())
  5. 礼貌地抓取

    AI 爬虫也是爬虫:robots.txt 和网站条款对它同样适用,平稳的速度也比突发的大量请求更体谅网站。check_robots_txt=True 会跳过被禁止的网址。在 0.9.4 中,这个 robots.txt 请求直接从你的机器发出,不经过代理,时限两秒,取不到文件时一律视为允许。

轮换 IP 与粘性 IP

Crawl4AI 为每个代理项保留一个浏览器上下文并重复使用。测试中,经同一代理项的两次抓取共用了一条隧道,而共用的隧道从同一个地址出去。住宅代理选“随机 IP”时,出口随新连接更换,并不等于每个页面都换。

先登录再看几个页面的流程,住宅代理请用“粘性 IP”,或使用静态 ISP IP。在 CrawlerRunConfig 上设置 proxy_session_id,RoundRobinProxyStrategy 就会让共用这个 id 的所有抓取固定使用列表中的同一项。

大范围抓取公开页面适合“随机 IP”,请求会分散到许多住宅地址上。

常见错误与解决办法

Page.goto: Timeout 60000ms exceeded

用户名或密码错误时就会这样:Chromium 不断重试代理登录,直到页面超时,也不会报告 407。调大 page_timeout 之前,先检查凭据。

net::ERR_PROXY_CONNECTION_FAILED

浏览器连不上 HOST:PORT。与服务页面核对两者,并确认服务仍然有效。

Blocked by anti-bot protection: Structural: minimal_text on small page

这是 Crawl4AI 自带的拦截检测把几乎没有文字的页面判定为被拦截,尽管网站返回了 200。api.ipify.org 的纯文本回复会触发它,上面用的 ?format=json 地址则不会。

ValueError: Invalid proxy string format

from_string 按冒号切分一行,并要求正好四段。密码里有冒号时就会出错;这一项请改用 ProxyConfig(server=..., username=..., password=...) 构造。

UserWarning: The 'proxy' parameter is deprecated

代码照搬了旧教程里的 BrowserConfig(proxy=...)。像第 2 步那样把这个值移到 proxy_config。

选择哪条产品线

给模型准备数据的抓取,往往是把很多页面各读一遍。目标网站接受服务器流量时,数据中心 IP 能把成本压低。遇到封锁数据中心 IP 段的网站就用住宅代理,同时让页面尽量轻:住宅代理按 GB 计费,而在 BrowserConfig 里设置 text_mode=True 会让浏览器跳过图片。

卡在某一步了?

把命令和报错贴到 Discord,记得先删掉密码。那里的人大多遇到过这些错误。

加入 Discorddiscord.gg/proxypanda
$5 起步去 Discord 问