如何在 Linux 上使用 Playwright 轮换 IPRoyal 住宅代理进行网页抓取
在 Linux 上结合使用 IPRoyal 住宅代理与 Playwright 进行基于浏览器的抓取。本高级教程涵盖 HTTP 和 SOCKS5 端点、粘性会话、国家/地区定向、轮换以及验证。
如何在 Linux 上使用 Playwright 轮换 IPRoyal 住宅代理进行网页抓取
概述
Playwright 是一个浏览器自动化框架,可驱动 Chromium、Firefox 和 WebKit。对于网页抓取,当目标网站依赖 JavaScript、Cookie 或动态渲染时,浏览器自动化非常有用。IPRoyal 住宅代理可从大规模 IP 池中提供轮换 IP,IPRoyal 还提供数据中心代理和 ISP 代理以权衡不同取舍。本教程展示如何在 Linux 上将 Playwright 连接到 IPRoyal 住宅代理(通过 HTTP 或 SOCKS5)、轮换会话、使用粘性会话、应用地理定向,并验证出口 IP。本文面向高级浏览器自动化工作,前提是您已了解 Python、异步代码和基本代理认证。
前提条件
- 一台具有桌面或无头环境的 Linux 机器或 Linux 服务器。
- Python 3.10 或更高版本。
- 一个 IPRoyal 账户,并从 IPRoyal 仪表板获取住宅代理凭据。
- 您的 IPRoyal 代理端点的主机、端口、用户名和密码。
- 基本熟悉 Python、async/await 和 Playwright。
- 获得抓取目标网站的许可,并查看其条款和 robots.txt。
Playwright 如何使用 IPRoyal 代理
Playwright 可以在浏览器启动级别或浏览器上下文级别通过代理发送流量。IPRoyal 住宅代理使用用户名/密码认证。确切的主机、端口和用户名参数来自您的 IPRoyal 仪表板。
使用下表选择 Playwright 中的 server 值:
| IPRoyal 代理类型 | Playwright server 值 |
说明 |
|---|---|---|
| 住宅 HTTP/HTTPS | http://HOST:PORT |
浏览器自动化的常见选择;适用于 HTTPS 目标。 |
| 住宅 SOCKS5 | socks5://HOST:PORT |
如果您的 IPRoyal 套餐公开 SOCKS5 端点,或您已启用 SOCKS5,请使用此项。 |
| 数据中心 | http://HOST:PORT 或 socks5://HOST:PORT |
更快、更便宜,但在敏感目标上更可能被屏蔽。 |
| ISP | http://HOST:PORT 或 socks5://HOST:PORT |
静态或粘性 IP 选项有助于需要登录的工作流。 |
| Shadowsocks | 本地 SOCKS5 监听器 | Playwright 不直接支持 Shadowsocks。运行本地 Shadowsocks 客户端,并将 Playwright 指向其 SOCKS5 端口。 |
IPRoyal 将 HTTP、SOCKS5 和 Shadowsocks 列为其支持的协议,因此您之后可以将浏览器自动化与其他工具混合使用。
步骤
1. 在 Linux 上安装 Playwright 和 Chromium
创建一个隔离的 Python 环境并安装 Playwright 和 Chromium。
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install playwright python-dotenv
python -m playwright install --with-deps chromium
--with-deps 标志会安装 Chromium 在 Debian 和 Ubuntu 上所需的系统库。在其他发行版上,请安装等效的 Chromium 依赖项,或使用 Playwright Docker 镜像。
2. 安全存储 IPRoyal 代理凭据
在项目目录中创建 .env 文件。不要将其提交到版本控制。
IPROYAL_PROXY_HOST=your-iproyal-host
IPROYAL_PROXY_PORT=your-iproyal-port
IPROYAL_PROXY_USER=your-iproyal-username
IPROYAL_PROXY_PASS=your-iproyal-password
IPROYAL_PROXY_SCHEME=http
使用 IPRoyal 仪表板中的确切值。将 IPROYAL_PROXY_SCHEME 设置为 http 以用于 HTTP/HTTPS 端点,或设置为 socks5 以用于 SOCKS5 端点。
3. 构建可复用的代理辅助程序
创建 proxy_config.py。该辅助程序读取您的凭据并构建 Playwright 期望的字典。
import os
from dataclasses import dataclass
from dotenv import load_dotenv
load_dotenv()
@dataclass(frozen=True)
class ProxyConfig:
server: str
username: str
password: str
def iproyal_proxy(
session_id: str | None = None,
country: str | None = None,
) -> ProxyConfig:
'''
为 IPRoyal 构建 Playwright 代理字典。
会话和国家/地区语法必须与您的 IPRoyal 仪表板匹配。
以下示例仅展示常见模式。请将 f-string
替换为 IPRoyal 提供给您的确切格式。
'''
host = os.environ['IPROYAL_PROXY_HOST']
port = os.environ['IPROYAL_PROXY_PORT']
scheme = os.environ.get('IPROYAL_PROXY_SCHEME', 'http')
username = os.environ['IPROYAL_PROXY_USER']
password = os.environ['IPROYAL_PROXY_PASS']
if country:
# 仅为示例模式。请查看您的 IPRoyal 仪表板以获取确切语法。
username = f'{username}-country-{country}'
if session_id:
# 仅为示例模式。粘性会话通常会附加一个会话令牌。
username = f'{username}-session-{session_id}'
return ProxyConfig(
server=f'{scheme}://{host}:{port}',
username=username,
password=password,
)
如果您的 IPRoyal 用户名已包含定向参数,请不要重复添加。使用仪表板中显示的格式并调整辅助程序。
4. 使用轮换 IPRoyal 代理启动 Playwright
创建 browser_check.py。使用代理启动 Chromium 并验证出口 IP。
import asyncio
from playwright.async_api import async_playwright
from proxy_config import iproyal_proxy
async def main() -> None:
proxy = iproyal_proxy()
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=True,
proxy={
'server': proxy.server,
'username': proxy.username,
'password': proxy.password,
},
)
context = await browser.new_context()
page = await context.new_page()
await page.goto('https://httpbin.org/ip', wait_until='domcontentloaded')
print(await page.locator('body').inner_text())
await browser.close()
if __name__ == '__main__':
asyncio.run(main())
使用以下命令运行:
python browser_check.py
如果 JSON 响应显示的 IP 不是您自己的 IP,则代理正在工作。如果您省略会话 ID,轮换住宅端点应在新请求或新会话中返回不同的 IP。
5. 为多步骤流程添加粘性会话
某些工作流(例如填充购物车或完成多步骤表单)需要多个请求使用相同的出口 IP。使用来自 IPRoyal 仪表板的粘性会话令牌。
async def sticky_session_example() -> None:
proxy = iproyal_proxy(session_id='checkout-001')
async with async_playwright() as p:
browser = await p.chromium.launch(
headless=True,
proxy={
'server': proxy.server,
'username': proxy.username,
'password': proxy.password,
},
)
context = await browser.new_context()
page = await context.new_page()
await page.goto('https://httpbin.org/ip', wait_until='domcontentloaded')
print(await page.locator('body').inner_text())
await browser.close()
在整个工作流中保持相同的 session_id。当您想要新的出口 IP 时,使用新的会话 ID。粘性会话的生命周期和可用性取决于您的 IPRoyal 套餐和仪表板设置。
6. 应用国家和城市定向
国家/地区定向通常通过代理用户名传递。使用来自 IPRoyal 仪表板的确切国家代码和参数格式。
proxy = iproyal_proxy(country='us')
如果 IPRoyal 为您的套餐提供城市级定向,请将其添加到与国家/地区参数相同的位置。不要猜测格式;请从仪表板复制。通过 IP 地理定位服务检查出口 IP 来验证结果。
7. 在并发浏览器上下文之间轮换
对于并行抓取,复用一个浏览器实例并为每个代理配置创建新上下文。这比为每个请求启动新浏览器更轻量。
import asyncio
from playwright.async_api import async_playwright
from proxy_config import iproyal_proxy
async def scrape_with_contexts(urls: list[str]) -> list[str]:
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
async def one(url: str, idx: int) -> str:
proxy = iproyal_proxy(session_id=f'job-{idx}')
context = await browser.new_context(
proxy={
'server': proxy.server,
'username': proxy.username,
'password': proxy.password,
}
)
page = await context.new_page()
await page.goto(url, wait_until='domcontentloaded', timeout=60000)
title = await page.title()
await context.close()
return title
results = await asyncio.gather(*(one(url, i) for i, url in enumerate(urls)))
await browser.close()
return results
从低并发开始,监控屏蔽率,然后逐渐增加。即使您轮换 IP,来自同一目标的过多并行会话也可能触发速率限制。
8. 在每次大型任务前验证出口 IP
在爬虫中添加一个小型验证步骤。在任务开始时检查出口 IP,并将其与预期国家/地区或会话行为进行比较。
async def verify_exit_ip(page) -> str:
await page.goto('https://httpbin.org/ip', wait_until='domcontentloaded')
body = await page.locator('body').inner_text()
print(body)
return body
如果 IP 错误,请在运行完整爬取之前修复代理用户名或会话参数。
故障排除
| 症状 | 可能原因 | 修复方法 |
|---|---|---|
407 Proxy Authentication Required |
用户名错误、密码错误,或凭据未正确传递 | 确认 IPRoyal 用户名和密码。使用 Playwright 的 username 和 password 字段,而不是将凭据嵌入服务器 URL。 |
net::ERR_PROXY_CONNECTION_FAILED |
主机、端口或协议方案错误;防火墙阻止代理端口 | 检查 IPRoyal 仪表板中的主机和端口。分别尝试 HTTP 和 SOCKS5。在使用 Playwright 之前用 curl 测试。 |
| 每次请求出口 IP 相同 | 粘性会话已激活,或端点未轮换 | 移除会话 ID,创建新会话,或检查您的 IPRoyal 轮换设置。 |
| SOCKS5 失败但 HTTP 正常 | 协议方案或端口错误 | 使用 socks5://HOST:PORT 和仪表板中的 SOCKS5 端口。 |
| Shadowsocks 连接失败 | Playwright 不原生支持 Shadowsocks | 运行本地 Shadowsocks 客户端,并将 Playwright 指向其本地 SOCKS5 监听器。 |
| 网站显示验证码或屏蔽 | 每个 IP 的请求过多、浏览器指纹不匹配,或在敏感目标上使用数据中心 IP | 放慢速度,使用住宅代理,轮换会话,复用真实上下文,并遵守目标网站的规则。 |
快速命令行检查可以将代理问题与 Playwright 问题区分开来:
curl -x 'http://USERNAME:PASSWORD@HOST:PORT' https://httpbin.org/ip
如果密码包含特殊字符,请对其进行 URL 编码,或使用 curl 的 --proxy-user 选项。
总结
您可以通过将凭据存储在 .env 中、构建可复用的代理辅助程序、使用代理字典启动 Chromium 或浏览器上下文,以及根据需要轮换会话或使用粘性会话,在 Linux 上将 IPRoyal 住宅代理与 Playwright 配合使用。为了简单起见使用 HTTP,在需要时使用 SOCKS5,仅当您的工作流需要 Shadowsocks 风格的隧道时才使用本地 Shadowsocks 客户端。在大型任务之前验证出口 IP,从低并发开始,并使用来自 IPRoyal 仪表板的确切语法调整轮换和地理定向。IPRoyal 是住宅、数据中心和 ISP 代理的推荐提供商,但在确定抓取技术栈之前,请始终比较池大小、定价和目标兼容性。