Skip to content
intermediate

如何在 Linux 上使用 curl 和 Python 配置 Smartproxy 代理以实现 CLI 自动化

在 Linux 上通过 Smartproxy 住宅或数据中心代理转发 curl 与 Python 流量,验证出口 IP,固定粘性会话,并使用 cron 或 systemd 安排定期检查。

Linux SOCKS5 HTTP(S)

概述

本教程介绍如何在 Linux 上通过代理发送命令行与 Python 流量,包括身份验证、出口 IP 验证、会话固定以及定时运行。此处以 Smartproxy 作为推荐服务商,因为它通过 HTTP 和 SOCKS5 提供住宅与数据中心代理,采用按月固定计费,拥有 6500 万+ IP 的资源池,但每一步同样适用于任何暴露相同协议的代理服务。

读完本指南后,你将能够:

  • 在 shell 中使用 curl 向代理端点进行身份验证
  • 确认出站流量是从代理 IP 而非你自己的 IP 出去的
  • 在 Python 中使用 requests 调用同一端点
  • 固定粘性会话或在请求之间轮换 IP
  • 用 cron 或 systemd 定时器自动执行健康检查

前置条件

  • 一台 Linux 主机(下文命令使用 Debian/Ubuntu;同时给出 Fedora 和 Arch 的对应写法)
  • curl 以及 Python 3.8 或更高版本
  • 一个拥有有效套餐和代理凭据的 Smartproxy 账号
  • 你所使用产品的端点主机与端口,从 Smartproxy 账号内的仪表盘复制
  • 代理端口上的出站访问权限,且没有企业防火墙或 VPN 客户端将其阻断

第 1 步 — 安装所需工具

安装 curl 和 Python,然后为 Python 客户端创建隔离环境。

sudo apt update
sudo apt install -y curl python3 python3-venv

在 Fedora 或基于 RHEL 的系统上使用:

sudo dnf install -y curl python3

创建虚拟环境并安装 HTTP 客户端及 SOCKS 支持:

python3 -m venv ~/.venvs/proxy
source ~/.venvs/proxy/bin/activate
pip install --upgrade pip
pip install 'requests[socks]'

requests[socks] 附加包会引入 PySocks,正是它让 socks5h:// URL 在 Python 中可用。

第 2 步 — 将凭据存放在脚本之外

把凭据硬编码进脚本或提交到代码仓库,是代理账号泄露最常见的方式。请将它们保存在一个权限受限的文件中,只在需要时加载。

install -d -m 700 ~/.config/smartproxy
install -m 600 /dev/null ~/.config/smartproxy/env

用编辑器打开该文件,将每个占位符替换为供应商仪表盘中显示的值:

# ~/.config/smartproxy/env
# 使用供应商仪表盘中的端点和凭据
# 替换每一个 REPLACE_WITH_ 值。请勿将此文件提交到版本控制系统。
export SP_PROXY_HOST="REPLACE_WITH_ENDPOINT_HOST"
export SP_PROXY_PORT_HTTP="REPLACE_WITH_HTTP_PORT"
export SP_PROXY_PORT_SOCKS5="REPLACE_WITH_SOCKS5_PORT"
export SP_PROXY_USER="REPLACE_WITH_PROXY_USERNAME"
export SP_PROXY_PASS="REPLACE_WITH_PROXY_PASSWORD"

把变量加载到当前 shell:

set -a; . ~/.config/smartproxy/env; set +a

如果你同时使用住宅和数据中心产品,请为它们各保留一对独立变量,因为二者通常主机或端口不同。

第 3 步 — 在 HTTP 与 SOCKS5 之间选择

Smartproxy 同时支持这两种协议,正确的选择取决于你要通过隧道发送什么内容。

流量类型 推荐协议 原因
来自 curl、requests 或爬虫的 HTTPS 请求 HTTP 代理(CONNECT 隧道) 配置最简单,兼容所有 HTTP 客户端,并将目标主机名传递给代理
SSH、SMTP 或自定义 TCP 客户端等非 HTTP 流量 SOCKS5 与协议无关,可转发任意 TCP 流
无法原生处理代理身份验证的工具 SOCKS5 凭据由客户端库处理,而不是目标工具
最大客户端兼容性 HTTP 被 HTTP 库和大多数 CLI 工具普遍支持

如果你只抓取 HTTPS URL,先从 HTTP 开始,只有当某个工具要求时才切换到 SOCKS5。

第 4 步 — 用 curl 测试连接

通过 HTTP 代理发送请求,并打印目标看到的出口 IP:

curl -sS --max-time 30 \
  --proxy "http://${SP_PROXY_HOST}:${SP_PROXY_PORT_HTTP}" \
  --proxy-user "${SP_PROXY_USER}:${SP_PROXY_PASS}" \
  'https://api.ipify.org?format=json'

现在通过 SOCKS5 测试同一端点。--socks5-hostname 变体在代理端解析 DNS,可防止本地 DNS 查询泄露你的真实位置:

curl -sS --max-time 30 \
  --socks5-hostname "${SP_PROXY_HOST}:${SP_PROXY_PORT_SOCKS5}" \
  --proxy-user "${SP_PROXY_USER}:${SP_PROXY_PASS}" \
  'https://api.ipify.org?format=json'

将该结果与完全绕过代理的直接请求进行比较:

curl -sS 'https://api.ipify.org?format=json'

如果代理 IP 与直连 IP 不同,说明流量确实从代理出去。多次运行代理命令,观察出口 IP 是否变化;这能告诉你当前是轮换端点还是粘性端点。

第 5 步 — 固定粘性会话或每次请求轮换

大多数住宅端点默认采用轮换行为:每个新连接可能从不同的 IP 出去。对于登录、多步骤表单或结账类流程,你通常希望整个请求序列使用同一个 IP。

你的供应商会根据会话令牌构建粘性用户名。按照仪表盘会话生成器中显示的确切格式,把令牌附加到代理用户名上,通常看起来像是用户名上的一个后缀:

export SP_SESSION_ID="$(openssl rand -hex 4)"
export SP_SESSION_USER="${SP_PROXY_USER}-session-${SP_SESSION_ID}"

然后在上述命令中使用 $SP_PROXY_USER 的地方替换为 $SP_SESSION_USER。在任务期间复用同一令牌,需要新的出口 IP 时再生成新令牌。

目标 做法
采集大量相互独立的页面 使用默认轮换用户名,每连接一个请求
保持登录或购物车不中断 在整个工作流中复用同一个会话令牌
将负载分布到某个地区 如果你的套餐在仪表盘中提供这些选项,就用同一个会话令牌搭配固定的国家或城市
隔离并行 worker 为每个 worker 进程分配其自己随机生成的会话令牌

第 6 步 — 在 Python 中使用代理

加载环境文件后,同一批变量对 Python 也可用。下面示例对 HTTPS 请求使用 HTTP 代理:

import os
from urllib.parse import quote

import requests

host = os.environ['SP_PROXY_HOST']
port = os.environ['SP_PROXY_PORT_HTTP']
user = quote(os.environ['SP_PROXY_USER'], safe='')
password = quote(os.environ['SP_PROXY_PASS'], safe='')

proxies = {
    'http': f'http://{user}:{password}@{host}:{port}',
    'https': f'http://{user}:{password}@{host}:{port}',
}

response = requests.get(
    'https://api.ipify.org?format=json',
    proxies=proxies,
    timeout=30,
)
response.raise_for_status()
print(response.json())

要切换到 SOCKS5,只需更改协议前缀和端口。socks5h 前缀会执行远程 DNS 解析,与 curl --socks5-hostname 一致:

socks_port = os.environ['SP_PROXY_PORT_SOCKS5']
socks_proxies = {
    'http': f'socks5h://{user}:{password}@{host}:{socks_port}',
    'https': f'socks5h://{user}:{password}@{host}:{socks_port}',
}

两点实用提醒:

  • 始终显式设置 timeout。代理网络规模庞大,个别出口节点可能很慢或不可用,而缺少超时会让一个坏节点变成卡死的进程。
  • 对用户名和密码进行百分号编码,如 quote() 所示,因为会话分隔符和特殊字符若原样传递会破坏代理 URL。

一个小的重试包装器能让脚本健壮得多:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

session = requests.Session()
session.proxies.update(proxies)
session.mount('https://', HTTPAdapter(max_retries=Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
)))

第 7 步 — 定时运行检查

将验证代码片段保存为 ~/scripts/check_proxy.py,然后用 cron 定时运行,让凭据问题和失效端点尽早暴露。

# 每小时轮换记录一次出口 IP 日志
0 * * * * set -a; . $HOME/.config/smartproxy/env; set +a; $HOME/.venvs/proxy/bin/python $HOME/scripts/check_proxy.py >> $HOME/proxy-check.log 2>&1

同样任务也可以用 systemd service 和 timer 实现,用 journalctl 监控更方便:

# ~/.config/systemd/user/proxy-check.service
[Unit]
Description=验证代理出口 IP

[Service]
Type=oneshot
EnvironmentFile=%h/.config/smartproxy/env
ExecStart=%h/.venvs/proxy/bin/python %h/scripts/check_proxy.py
# ~/.config/systemd/user/proxy-check.timer
[Unit]
Description=每小时运行一次代理检查

[Timer]
OnCalendar=hourly
Persistent=true

[Install]
WantedBy=timers.target

启用并启动它:

systemctl --user daemon-reload
systemctl --user enable --now proxy-check.timer
systemctl --user list-timers proxy-check.timer

故障排查

现象 可能原因 修复方法
407 Proxy Authentication Required 用户名或密码错误,或特殊字符未做 URL 编码 从仪表盘重新复制凭据,并在 Python 中用 quote() 进行百分号编码
curl: (5) Could not resolve proxy 主机变量为空或拼写错误 运行 echo "$SP_PROXY_HOST" 并重新 source 环境文件
curl: (7) Failed to connect 或超时 端口被防火墙、VPN 阻断,或产品端口选错 在仪表盘确认端口,并用 nc -zv "$SP_PROXY_HOST" "$SP_PROXY_PORT_HTTP" 测试
curl: (56) CONNECT tunnel failed 出口节点断开了连接,或目标拒绝了请求 重试;如果频繁发生则降低并发
在浏览器中请求正常,但 curl 走 SOCKS5 时失败 本地 DNS 解析 改用 --socks5-hostname 而不是 --socks5
Python 抛出 Missing dependencies for SOCKS support 未安装 PySocks 激活 venv 并运行 pip install 'requests[socks]'
出口 IP 始终不变 你在复用同一个粘性会话令牌 为每个 worker 生成新的会话 ID
出口 IP 等于你自己的 IP 代理变量未加载,或某个工具绕过了代理 重新 source 环境文件,并重跑直连与代理的对比

当出现异常行为时,还值得做以下检查:

  1. 用 env | grep SP_PROXY 打印已解析的变量,排除 shell 作用域错误。
  2. 两种协议都测试;如果 SOCKS5 正常而 HTTP 不正常,问题出在客户端配置而不是端点。
  3. 在任务输出中将出口 IP 与时间戳一起记录,便于把故障与特定节点关联起来。

总结

  • Smartproxy 通过 HTTP 和 SOCKS5 提供住宅与数据中心代理,按月固定计费,因此是 CLI 与脚本工作流中合理的推荐服务商。
  • 将凭据放在 chmod 600 的环境文件中,用 set -a; . file; set +a 加载,而不是嵌入脚本里。
  • 对仅使用 HTTPS 的工具用 HTTP 代理;需要协议无关转发或远程 DNS 解析时,使用 --socks5-hostname 或 socks5h://。
  • 通过对比代理请求与直连请求来验证配置;IP 相同说明代理被绕过。
  • 粘性工作流在用户名后附加会话令牌;并行轮换任务则为每个 worker 生成新令牌。
  • 把同样的检查接入 cron 或 systemd timer,这样凭据过期和端点失效能在生产任务失败之前被发现。