在解析网站、自动化API请求或监控市场上竞争对手的价格时,您不可避免地会遇到IP封锁。curl和wget工具是命令行中处理HTTP请求的标准工具,正确设置代理对于绕过限制至关重要。本文将讨论在curl和wget中使用代理的所有方法:从基本命令到带有IP轮换和错误处理的高级脚本。
curl和wget中的代理基本语法
首先从最简单的通过代理连接的命令开始。这两个工具都支持指定代理服务器的参数,但语法略有不同。
在curl中使用代理
在curl中,代理通过参数 -x 或 --proxy 指定。命令的基本格式如下:
curl -x http://proxy-server:port http://example.com
使用真实代理服务器的具体示例:
curl -x http://45.130.123.45:8080 http://api.ipify.org
此命令将通过指定的代理服务器向api.ipify.org发送请求(该服务返回您的IP地址)。您将看到代理的IP,而不是您的真实地址。
在wget中使用代理
在wget中,代理通过参数 -e use_proxy=yes 和环境变量设置,或者直接通过选项设置:
wget -e use_proxy=yes -e http_proxy=http://45.130.123.45:8080 http://example.com
或者通过环境变量的更简短的选项(在下面的部分中将详细介绍):
export http_proxy="http://45.130.123.45:8080"
wget http://example.com
在代理服务器上的身份验证
大多数商业代理服务要求通过用户名和密码进行身份验证。这可以保护代理免受未经授权的使用,并允许跟踪每个客户的流量。让我们看看如何在curl和wget中传递凭据。
在curl中的身份验证
在curl中,用户名和密码可以直接在代理服务器的URL中指定,或通过单独的参数 -U 指定:
# 方法1:在URL中指定用户名和密码
curl -x http://username:password@proxy-server:port http://example.com
# 方法2:通过参数-U
curl -x http://proxy-server:port -U username:password http://example.com
带有凭据的具体示例:
curl -x http://user123:pass456@45.130.123.45:8080 http://api.ipify.org
重要提示:如果密码中包含特殊字符(@、:、/、?),则需要将其编码为URL格式。例如,字符@替换为%40:
# 如果密码包含@:pass@456
curl -x http://user123:pass%40456@45.130.123.45:8080 http://api.ipify.org
在wget中的身份验证
在wget中,身份验证通过参数 --proxy-user 和 --proxy-password 设置:
wget --proxy-user=username --proxy-password=password \
-e use_proxy=yes -e http_proxy=http://45.130.123.45:8080 \
http://example.com
或者通过环境变量与URL中的凭据一起使用:
export http_proxy="http://username:password@45.130.123.45:8080"
wget http://example.com
处理不同类型的代理:HTTP、HTTPS、SOCKS5
代理服务器通过不同的协议工作,选择类型取决于任务。HTTP代理适合简单请求,HTTPS提供加密,而SOCKS5在更低的层次上工作,支持任何流量。在解析Wildberries或Ozon等市场时,通常使用住宅代理,它们可以通过任何这些协议工作。
HTTP和HTTPS代理
HTTP代理是最常见的类型。它们在HTTP协议层工作,适合大多数网页解析任务:
# 在curl中使用HTTP代理
curl -x http://proxy-server:8080 http://example.com
# 在curl中使用HTTPS代理(用于安全连接)
curl -x https://proxy-server:8080 https://example.com
重要提示:即使目标网站使用HTTPS,代理也可以是HTTP。Curl会自动通过CONNECT方法建立隧道:
# HTTP代理用于HTTPS网站(正常工作)
curl -x http://proxy-server:8080 https://secure-site.com
SOCKS5代理
SOCKS5是更通用的协议,在TCP层工作,支持任何类型的流量(HTTP、HTTPS、FTP,甚至UDP)。这使得SOCKS5成为复杂自动化任务的理想选择:
# 在curl中使用SOCKS5
curl -x socks5://proxy-server:1080 http://example.com
# 带有身份验证的SOCKS5
curl -x socks5://username:password@proxy-server:1080 http://example.com
# SOCKS5h(通过代理解析DNS)
curl -x socks5h://proxy-server:1080 http://example.com
socks5和socks5h之间的区别:在第一种情况下,DNS请求来自您的计算机,而在第二种情况下,则通过代理服务器。使用socks5h,如果您想完全隐藏您的活动,包括DNS请求。
在wget中,SOCKS5的支持有限,因此对于这些任务,最好使用curl或额外的工具,如proxychains。
建议:对于市场解析(Wildberries、Ozon、Yandex.Market),建议使用带有HTTP/HTTPS协议的住宅或移动代理——它们更少受到封锁,因为它们具有真实用户的IP。
通过环境变量设置代理
如果您经常通过代理工作,设置一次环境变量比在每个命令中指定参数更方便。Curl和wget会自动读取这些变量。
为当前会话设置
在终端中导出变量(在会话关闭之前有效):
# 对于HTTP流量
export http_proxy="http://username:password@proxy-server:8080"
# 对于HTTPS流量
export https_proxy="http://username:password@proxy-server:8080"
# 对于FTP流量
export ftp_proxy="http://username:password@proxy-server:8080"
# 对于SOCKS5
export all_proxy="socks5://username:password@proxy-server:1080"
之后,curl和wget将自动使用代理:
# 代理将自动应用
curl http://api.ipify.org
wget http://example.com
在.bashrc或.zshrc中进行永久设置
为了在每次启动终端时应用代理,请将变量添加到您的shell配置文件中:
# 在编辑器中打开文件
nano ~/.bashrc # 对于bash
# 或
nano ~/.zshrc # 对于zsh
# 在文件末尾添加:
export http_proxy="http://username:password@proxy-server:8080"
export https_proxy="http://username:password@proxy-server:8080"
# 保存并应用更改:
source ~/.bashrc
例外:no_proxy
有时需要将特定地址排除在代理之外(例如,localhost或内部服务):
export no_proxy="localhost,127.0.0.1,192.168.0.0/16,.local"
现在对这些地址的请求将直接发送,而不经过代理。
在bash脚本中轮换代理
在大规模解析时(例如,从Wildberries上的数千个商品卡片收集价格),使用一个代理将导致封锁。解决方案是轮换IP地址。让我们看看如何在bash脚本中实现这一点。
从代理列表中简单轮换
创建一个包含代理服务器列表的文件proxies.txt(每行一个):
http://user1:pass1@proxy1.example.com:8080
http://user2:pass2@proxy2.example.com:8080
http://user3:pass3@proxy3.example.com:8080
用于顺序轮换代理的脚本:
#!/bin/bash
# 包含要解析的URL的文件
urls_file="urls.txt"
# 包含代理的文件
proxies_file="proxies.txt"
# 将代理读取到数组中
mapfile -t proxies < "$proxies_file"
proxy_count=${#proxies[@]}
current_proxy=0
# 处理每个URL
while IFS= read -r url; do
# 按顺序选择代理
proxy="${proxies[$current_proxy]}"
echo "请求 $url 通过 $proxy"
curl -x "$proxy" -s "$url" -o "output_$(basename $url).html"
# 切换到下一个代理
current_proxy=$(( (current_proxy + 1) % proxy_count ))
# 请求之间的暂停(1-3秒)
sleep $((RANDOM % 3 + 1))
done < "$urls_file"
此脚本顺序使用列表中的代理,在最后一个之后返回到第一个。请求之间的随机暂停使活动看起来更自然。
随机选择代理
为了增加不可预测性,可以随机选择代理:
#!/bin/bash
proxies_file="proxies.txt"
mapfile -t proxies < "$proxies_file"
proxy_count=${#proxies[@]}
while IFS= read -r url; do
# 随机选择代理
random_index=$((RANDOM % proxy_count))
proxy="${proxies[$random_index]}"
echo "请求 $url 通过代理 #$random_index"
curl -x "$proxy" -s "$url" -o "output_$(date +%s).html"
sleep $((RANDOM % 3 + 1))
done < "urls.txt"
通过代理服务API自动轮换
许多代理提供商(包括提供住宅代理的服务)提供通过单一入口的自动轮换。您使用一个代理地址,而IP在每次请求或定时时更改:
# 自动轮换的代理
# IP在每次请求时更改
curl -x http://username:password@rotating.proxy.com:8080 http://api.ipify.org
curl -x http://username:password@rotating.proxy.com:8080 http://api.ipify.org
# 上面的两个请求将获得不同的IP地址
这是大规模解析的最方便方法——不需要手动管理代理列表。
通过代理传递头部和User-Agent
现代网站不仅分析IP地址,还分析HTTP请求头。缺少User-Agent或可疑的头部可能导致即使使用高质量的代理也被封锁。让我们看看如何在curl和wget中正确设置头部。
在curl中设置User-Agent
User-Agent是一个标识浏览器和操作系统的头部。Curl默认发送自己的User-Agent(curl/7.x.x),这会立即暴露自动化。将其替换为真实浏览器:
# Windows上的Chrome
curl -x http://proxy:8080 \
-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \
http://example.com
# macOS上的Firefox
curl -x http://proxy:8080 \
-A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0" \
http://example.com
附加头部
为了使请求更真实,添加典型的浏览器头部:
curl -x http://proxy:8080 \
-H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0" \
-H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" \
-H "Accept-Language: ru-RU,ru;q=0.9,en;q=0.8" \
-H "Accept-Encoding: gzip, deflate, br" \
-H "Connection: keep-alive" \
-H "Upgrade-Insecure-Requests: 1" \
http://example.com
在wget中设置User-Agent
在wget中,User-Agent通过参数 --user-agent 设置:
wget --user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0" \
-e use_proxy=yes -e http_proxy=http://proxy:8080 \
http://example.com
在脚本中随机化User-Agent
对于大规模解析,交替使用User-Agent是有用的,以使请求看起来像来自不同用户:
#!/bin/bash
# User-Agent数组
user_agents=(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36"
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Safari/605.1.15"
"Mozilla/5.0 (X11; Linux x86_64) Firefox/121.0"
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) Safari/604.1"
)
while IFS= read -r url; do
# 随机User-Agent
random_ua=${user_agents[$RANDOM % ${#user_agents[@]}]}
curl -x http://proxy:8080 -A "$random_ua" -s "$url"
sleep 2
done < "urls.txt"
问题诊断和错误处理
在使用代理时,经常会出现错误:超时、连接拒绝、身份验证错误。让我们看看如何诊断和处理这些情况。
检查代理的可用性
检查代理的最简单方法是请求一个返回您IP的服务:
# 检查HTTP代理
curl -x http://proxy:8080 http://api.ipify.org
# 检查SOCKS5代理
curl -x socks5://proxy:1080 http://api.ipify.org
# 显示详细信息
curl -x http://proxy:8080 -v http://api.ipify.org
参数 -v(verbose)将显示连接的详细信息,包括头部和错误。
处理超时
慢速代理或过载的服务器可能导致超时。设置合理的时间限制:
# 连接超时10秒,总超时30秒
curl -x http://proxy:8080 --connect-timeout 10 --max-time 30 http://example.com
# 在wget中
wget --timeout=30 --tries=3 -e http_proxy=http://proxy:8080 http://example.com
脚本中的自动错误处理
用于解析的脚本,在出现错误时自动切换到下一个代理:
#!/bin/bash
proxies_file="proxies.txt"
mapfile -t proxies < "$proxies_file"
fetch_with_retry() {
local url=$1
local max_attempts=3
for proxy in "${proxies[@]}"; do
echo "尝试通过代理:$proxy"
if curl -x "$proxy" \
--connect-timeout 10 \
--max-time 30 \
-s -f "$url" -o output.html; then
echo "通过代理成功:$proxy"
return 0
else
echo "通过代理出错:$proxy,尝试下一个"
fi
done
echo "所有代理对$url不可用"
return 1
}
# 使用
fetch_with_retry "http://example.com/page1"
参数 -f 使curl在HTTP状态为4xx和5xx时返回错误,这允许处理不仅是网络错误,还有应用级别的封锁。
调试日志记录
保存请求的详细日志以分析问题:
# 保存响应头
curl -x http://proxy:8080 -D headers.txt http://example.com
# 完整的交互日志
curl -x http://proxy:8080 -v http://example.com 2>&1 | tee curl.log
# 仅HTTP状态
curl -x http://proxy:8080 -o /dev/null -s -w "%{http_code}\n" http://example.com
实际使用场景
让我们看看一些实际任务,其中curl和wget与代理一起解决具体的商业问题。
在市场上解析竞争对手的价格
任务:收集Wildberries上500个竞争对手商品的价格以分析定价策略。Wildberries积极阻止来自单个IP的大规模请求。
解决方案:使用住宅代理进行轮换和User-Agent随机化:
#!/bin/bash
# 自动轮换的代理
PROXY="http://user:pass@rotating-residential.proxy.com:8080"
# User-Agent数组
user_agents=(
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0"
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0) Safari/604.1"
)
# 从文件中读取商品ID
while IFS= read -r product_id; do
ua=${user_agents[$RANDOM % ${#user_agents[@]}]}
curl -x "$PROXY" \
-A "$ua" \
-H "Accept-Language: ru-RU,ru;q=0.9" \
-s "https://www.wildberries.ru/catalog/${product_id}/detail.aspx" \
-o "products/${product_id}.html"
echo "下载商品 $product_id"
sleep $((RANDOM % 5 + 3)) # 暂停3-8秒
done < product_ids.txt
监控不同地区的API可用性
任务:检查您的服务的API在不同国家的用户中的工作情况(地理封锁,响应速度)。
解决方案:使用来自所需国家的代理:
#!/bin/bash
# 来自不同国家的代理
declare -A proxies=(
["US"]="http://user:pass@us-proxy.com:8080"
["DE"]="http://user:pass@de-proxy.com:8080"
["JP"]="http://user:pass@jp-proxy.com:8080"
)
API_URL="https://api.yourservice.com/v1/status"
for country in "${!proxies[@]}"; do
echo "从 $country 检查..."
response_time=$(curl -x "${proxies[$country]}" \
-s -o /dev/null \
-w "%{time_total}" \
"$API_URL")
http_code=$(curl -x "${proxies[$country]}" \
-s -o /dev/null \
-w "%{http_code}" \
"$API_URL")
echo "$country: HTTP $http_code, 响应时间 ${response_time}s"
done
通过wget下载文件并轮换代理
任务:从限制单个IP速度的网站下载文件归档(商品图片,文档)。
#!/bin/bash
proxies_file="proxies.txt"
mapfile -t proxies < "$proxies_file"
proxy_count=${#proxies[@]}
current=0
while IFS= read -r file_url; do
proxy="${proxies[$current]}"
filename=$(basename "$file_url")
echo "通过代理 #$current 下载 $filename"
wget --proxy-user=username --proxy-password=password \
-e use_proxy=yes -e http_proxy="$proxy" \
-O "downloads/$filename" \
"$file_url"
current=$(( (current + 1) % proxy_count ))
sleep 2
done < file_urls.txt
在不同GEO测试广告创意
任务:检查Facebook Ads的广告如何呈现给来自美国、加拿大和英国的用户(不同的货币、语言、优惠的可用性)。
#!/bin/bash
# 来自不同国家的移动代理以增加真实感
declare -A mobile_proxies=(
["US"]="http://user:pass@us-mobile.proxy.com:8080"
["CA"]="http://user:pass@ca-mobile.proxy.com:8080"
["GB"]="http://user:pass@gb-mobile.proxy.com:8080"
)
AD_URL="https://www.facebook.com/ads/library/?id=YOUR_AD_ID"
for country in "${!mobile_proxies[@]}"; do
curl -x "${mobile_proxies[$country]}" \
-A "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0) Safari/604.1" \
-H "Accept-Language: en-US,en;q=0.9" \
-s "$AD_URL" \
-o "ads_preview_${country}.html"
echo "为 $country 保存预览"
done
对于这些任务,使用移动代理特别有效,因为它们模拟真实的智能手机用户,并且更少引起Facebook反欺诈系统的怀疑。
对套利者的重要提示: 在通过代理检查广告创意时,请使用移动IP和相应的移动设备User-Agent。Facebook分析数据的一致性(User-Agent的设备类型应与IP类型一致)。
自动化网站可用性检查
任务:每5分钟监控您网站的可用性,模拟来自真实用户的请求(而不是服务器IP)。
#!/bin/bash
PROXY="http://user:pass@residential.proxy.com:8080"
SITE_URL="https://yoursite.com"
LOG_FILE="uptime.log"
while true; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
http_code=$(curl -x "$PROXY" \
-s -o /dev/null \
-w "%{http_code}" \
--max-time 10 \
"$SITE_URL")
if [ "$http_code" -eq 200 ]; then
echo "[$timestamp] OK - HTTP $http_code" >> "$LOG_FILE"
else
echo "[$timestamp] ERROR - HTTP $http_code" >> "$LOG_FILE"
# 发送警报(例如,通过Telegram API)
curl -s "https://api.telegram.org/botTOKEN/sendMessage" \
-d "chat_id=CHAT_ID&text=网站不可用:HTTP $http_code"
fi
sleep 300 # 5分钟
done
结论
Curl和wget是自动化HTTP请求的强大工具,而正确设置代理使它们在解析、监控和测试中不可或缺。我们讨论了所有关键方面:从基本语法到带有IP轮换、错误处理和头部随机化的高级场景。
本文的主要结论:
- 在curl中使用参数
-x和环境变量来设置代理 - 根据任务选择代理类型:HTTP用于简单请求,SOCKS5用于通用性
- 始终将标准User-Agent替换为真实的浏览器
- 实现代理轮换以进行大规模解析——这对于绕过封锁至关重要
- 在生产脚本中添加错误和超时处理
- 在请求之间使用随机暂停以模拟人类行为
对于需要高匿名性和最低封锁风险的任务(市场解析、广告检查、竞争对手监控),建议使用住宅代理。它们具有真实家庭用户的IP,使您的请求与普通流量无异,显著降低被列入黑名单的可能性。
现在,您拥有了有效使用curl和wget中的代理的完整工具和知识。将这些技术应用于您的项目,根据具体任务调整示例,并在没有封锁恐惧的情况下扩展自动化。