Google Colab 和 Jupyter Notebook 是快速编写和运行解析脚本的便捷工具,无需在本地计算机上安装 Python。但云笔记本有一个常被忽视的特点:所有请求都来自 Google 数据中心的 IP 地址,这些地址早已被反机器人系统识别,并几乎瞬间被封禁。在本文中,我们将讨论如何在 Colab 和 Jupyter 中正确连接代理,云环境施加的限制,以及如何构建解析以避免在前 50 个请求后崩溃。
为什么 Google Colab 比普通 PC 更容易被封禁
Colab 进行解析的主要问题是共享 IP 池。每次您启动笔记本时,Google 会分配一个来自其云范围(AS15169 及类似范围)的虚拟机 IP。这些范围早已被大多数反机器人系统列入黑名单:Cloudflare、DataDome、PerimeterX,以及 Wildberries、Ozon 和市场的内置保护系统会在瞬间识别它们。请求甚至无法到达网站——在检查 User-Agent 或行为之前,ASN(自主系统编号)过滤器就会将其拦截。
第二个原因是使用的广泛性。成千上万的开发者同时通过 Colab 运行解析器、机器人和机器学习脚本,因此这些 IP 在许多目标网站上的声誉早已“烧毁”,远在您发出请求之前。即使您每 10 秒发出一个精确的 GET 请求,网站也可能返回 403,仅仅是因为一个小时之前同一范围内有人以 500 个线程攻击服务器。
第三个原因是,通常情况下,运行在本地的 Jupyter 不会有这个问题(如果您有普通的家庭或办公 IP),但如果您通过 JupyterHub 在托管服务器或云服务提供商的容器中工作,情况就会变得和 Colab 一样。因此,对于云笔记本来说,“是否需要代理”的问题是明确的:没有它们,解析几乎无法在前几个请求之后继续。
哪种类型的代理适合云解析
选择代理类型取决于您解析的内容以及目标网站的保护程度。对于 Colab 和 Jupyter,还需要考虑一个细节:笔记本的会话是时间有限的,因此持久的 sticky 会话代理并不总是至关重要——更重要的是在一次运行中连接的稳定性。
| 代理类型 | 在 Colab/Jupyter 中何时使用 | 特点 |
|---|---|---|
| 数据中心代理 | 解析没有严格保护的网站、开放 API、静态页面 | 速度快,价格低,但在激进的网站上也可能被 ASN 封禁 |
| 住宅代理 | 解析 Wildberries、Ozon、Avito、Google、社交媒体的反机器人保护 | 真实用户的 IP,较少进入黑名单,延迟较高 |
| 移动代理 | 解析移动版本的网站、通过 API 访问 TikTok、Instagram | 最高的信任度,但价格更高,轮换速度较慢 |
对于大多数来自 Colab 的市场和搜索引擎解析任务,最佳平衡是使用带有每个请求轮换的住宅代理——这降低了因行为模式而被封禁的可能性,即使请求本身是从 Google 的云环境中发出的。
在 requests 和 urllib 中设置代理
在 Colab 中设置代理的基本方法与本地 Python 环境没有区别。唯一的区别在于,Colab 中的库通常需要通过 !pip install 进行安装,因为标准镜像并不总是包含所有必要的内容。
!pip install requests
import requests
proxy = {
"http": "http://login:[email protected]:9000",
"https": "http://login:[email protected]:9000"
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(
"https://example.com/catalog",
proxies=proxy,
headers=headers,
timeout=15
)
print(response.status_code)
print(response.text[:500])
重要的一点:在 Colab 中没有持久的配置文件,因此代理的登录名和密码必须硬编码(在发布笔记本时不安全),或者通过 google.colab.userdata 在 Colab 的环境变量中保存,或者通过 Colab Secrets 进行连接。这比将密码直接存储在代码中更方便,特别是当您与同事共享笔记本时。
from google.colab import userdata
proxy_login = userdata.get('PROXY_LOGIN')
proxy_pass = userdata.get('PROXY_PASS')
proxy_url = f"http://{proxy_login}:{proxy_pass}@gate.proxycove.com:9000"
proxies = {"http": proxy_url, "https": proxy_url}
在 Colab 中使用 Selenium 和无头 Chrome 的代理
如果网站通过 JavaScript 渲染内容(对于 Wildberries、Ozon、Avito 来说是典型情况),简单的 requests 不够——需要无头浏览器。在 Colab 中,这通常是 Selenium 和 Chromium,需要手动安装,因为基本镜像中没有它。
!apt-get update
!apt install chromium-chromedriver
!pip install selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--proxy-server=http://gate.proxycove.com:9000')
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://example.com/catalog")
print(driver.page_source[:500])
driver.quit()
问题在于,--proxy-server 标志不支持直接使用登录名和密码进行身份验证。对于需要身份验证的代理,在 Selenium 中要么使用 IP 身份验证(通过静态 IP 的白名单,这在 Colab 中不稳定,因为机器的 IP 在每次新启动时都会更改),要么动态生成带有代理凭据的 Chrome 扩展,要么使用像 selenium-wire 这样的库,通过它可以直接支持身份验证代理。
!pip install selenium-wire
from seleniumwire import webdriver
proxy_options = {
'proxy': {
'http': 'http://login:[email protected]:9000',
'https': 'http://login:[email protected]:9000',
}
}
driver = webdriver.Chrome(seleniumwire_options=proxy_options, options=chrome_options)
driver.get("https://example.com/catalog")
Jupyter Notebook:本地 vs 云端
在本地计算机上运行的 Jupyter Notebook(通过 Anaconda 或直接通过 pip)使用您的家庭或办公 IP——在这种情况下,代理仅用于掩盖或绕过地理限制,而不是为了避免数据中心的 ASN 封禁。在这种情况下,设置与普通 Python 脚本完全相同:同样的 requests,同样的 Selenium,没有安装驱动程序和系统包的限制。
如果您通过云服务使用 Jupyter,情况就会改变:在 VPS 上的 JupyterHub、Kaggle Notebooks、Deepnote、Binder 或企业云集群。在这些情况下,IP 再次属于服务提供商的数据中心,Colab 的所有问题都完全适用。与 Colab 的主要区别是,这些服务通常在会话期间 IP 更加稳定(在每次重启内核时不会更改),这简化了如果您的代理提供商支持的 IP 白名单设置。
实际结论是:如果解析对业务至关重要(例如,每日监控市场上竞争对手的价格),最好不要将免费云笔记本作为生产环境,而只将其用于开发和测试脚本,将最终的解析器迁移到具有固定 IP 和设置好的代理的服务器上。
破坏解析的云笔记本限制
除了 IP 声誉问题,Google Colab 还有一系列技术限制,这些限制直接影响解析的稳定性:
- 非活动超时。 Colab 的免费版本在 ~90 分钟的空闲后会关闭笔记本,并在 12 小时的连续工作后强制结束会话——长时间解析数千个页面需要分段进行,或将中间结果保存在 Google Drive 上。
- 每次新运行时更换 IP。 如果您断开并重新连接执行环境,虚拟机的 IP 地址会更改——这会破坏任何基于 IP 的白名单设置。
- 对出站连接的限制。 Google 限制来自同一虚拟机的并发网络连接数量,因此激进的多线程与数十个并行请求可能会受到 Colab 本身的限制,而不是网站的封锁。
- 没有持久存储,除非挂载磁盘。 Cookies、浏览器会话和代理连接的缓存会在每次重启时消失——对于需要身份验证的解析,必须明确将 Cookies 保存到 Google Drive 上的文件中。
- 不可预测的网络延迟。 Google 的云基础设施有时会出现延迟波动,因此请求的超时时间需要留有余地(15-30 秒,而不是标准的 5-10 秒)。
这些限制使 Colab 成为开发和调试解析器逻辑的优秀工具,但不适合长期的生产任务——对于这些任务,最好将准备好的脚本迁移到具有固定 IP 的 VPS 或专用服务器上。
代理轮换和循环中的错误处理
为了防止解析在第一次封禁时崩溃,代码中需要有重试逻辑并更换代理。以下是一个简单的带有轮换和错误处理的循环示例,可以直接在 Colab 中运行。
import requests
import time
import random
proxy_pool = [
"http://login:[email protected]:9000",
"http://login:[email protected]:9001",
"http://login:[email protected]:9002",
]
def get_with_retry(url, max_retries=5):
for attempt in range(max_retries):
proxy_url = random.choice(proxy_pool)
proxies = {"http": proxy_url, "https": proxy_url}
try:
response = requests.get(url, proxies=proxies, timeout=20)
if response.status_code == 200:
return response
else:
print(f"尝试 {attempt+1}: 状态 {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"尝试 {attempt+1}: 错误 {e}")
time.sleep(random.uniform(2, 5))
return None
result = get_with_retry("https://example.com/catalog")
if result:
print(result.status_code)
else:
print("所有尝试已用尽")
对于解析大型目录(例如,Wildberries 上的数千个商品卡片),此逻辑通常会进一步封装在任务队列中,在请求之间设置暂停,并将中间结果保存到 CSV 或数据库中,直接存储在 Google Drive 上,以便在 Colab 会话中断时不丢失进度。
在 Colab 中启动解析器前的检查清单
- 代理已连接并在主要循环之前通过单独的测试请求进行了测试
- 代理的登录名和密码存储在 Colab Secrets 中,而不是公开代码中
- 对于 JS 网站,使用 Selenium 与 selenium-wire 或已配置的授权扩展
- 代码中有重试逻辑,并在 403/429 错误时轮换代理
- 中间结果每 N 条记录保存到 Google Drive
- 请求的超时时间已根据可能的云网络延迟增加
- 请求的并行性受到限制,以避免达到 Colab 的出站连接限制
- 对于生产任务,计划将脚本迁移到具有固定 IP 的单独服务器上
结论
Google Colab 和云 Jupyter 非常适合快速开发和测试解析器逻辑,但由于共享的数据中心 IP,几乎总是在最初的步骤中需要代理。对于没有激进保护的简单网站,数据中心代理就足够了,而对于市场、搜索引擎和社交媒体的解析,住宅和移动 IP 更可靠,因为它们更少受到 ASN 过滤的影响。
如果您计划直接从 Colab 定期监控 Wildberries 或 Ozon 的价格,建议从 住宅代理 开始——它们提供稳定的访问,且不易被频繁封禁,而对于一次性测试脚本,可以使用更经济的数据中心代理,通过相同的方式通过 requests 或 Selenium 连接。