返回博客

如何诊断成功率低的原因

代理成功率是任何项目的关键指标。让我们探讨如何确定下降的原因并恢复效率。

📅2025年12月3日

如何诊断成功率低的原因:分步指南

成功率(Success Rate, SR)是成功请求占总尝试次数的百分比。当这个指标低于正常水平时,就会导致金钱、时间和数据的损失。但原因可能有很多:从错误的配置到目标服务器的封锁。在本文中,我们将探讨系统化的诊断方法并找到解决方案。

什么是成功率以及正常范围

成功率 (SR) = (成功请求数 / 总请求次数) × 100%

正常值取决于任务类型:

任务 正常 SR 临界水平
抓取公开数据 95–99% 低于 85%
SMM 自动化 90–97% 低于 80%
广告验证 98–99.5% 低于 95%
API 集成 99–99.9% 低于 98%

如果 SR 下降了 5-10% 偏离您的基线,这是一个需要诊断的信号。如果下降了 20% 以上,则需要立即采取行动。

诊断的第一步

步骤 1:检查日志和指标

收集过去 24-72 小时的数据:

  • SR 是在何时(确切时间)开始下降的?
  • 多少百分比的请求返回 407 (Proxy Authentication Required) 错误?
  • 多少百分比返回 429 (Too Many Requests) 错误?
  • 多少百分比是连接超时(connection timeout)?
  • 每秒请求数 (RPS) 是否发生变化?

步骤 2:隔离测试

使用一个简单的脚本来测试代理,不涉及您的应用程序:

import requests
import time

proxy = "http://proxy_ip:port"
proxies = {"http": proxy, "https": proxy}
target_url = "https://httpbin.org/ip"

success = 0
failed = 0

for i in range(100):
    try:
        response = requests.get(
            target_url, 
            proxies=proxies, 
            timeout=10,
            verify=False
        )
        if response.status_code == 200:
            success += 1
            print(f"✓ 第 {i+1} 次尝试:成功")
        else:
            failed += 1
            print(f"✗ 第 {i+1} 次尝试:状态码 {response.status_code}")
    except Exception as e:
        failed += 1
        print(f"✗ 第 {i+1} 次尝试:{str(e)}")
    time.sleep(0.5)

sr = (success / (success + failed)) * 100
print(f"\n成功率: {sr:.1f}%")
print(f"成功: {success}, 失败: {failed}")

如果此测试显示正常 SR,则问题出在您的代码或配置中。如果 SR 仍然很低,则问题出在代理或目标服务器上。

代理端问题

错误 407: Proxy Authentication Required

原因:

  • 凭据错误(用户名/密码)
  • 账户已过期
  • IP 地址未在白名单中(如果需要)
  • IP 轮换未工作或已禁用

解决方案:

import requests

# 住宅代理的正确格式
proxy = "http://login:password@proxy-host:port"
proxies = {"http": proxy, "https": proxy}

# 测试
response = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
print(response.text)

代理服务器过载

如果所有用户同时发送大量请求,可能会达到每秒请求数 (RPS) 限制。这种情况很少见,但确实会发生。

检查:

  • 您当前的峰值 RPS
  • 您的套餐限制
  • 日志中是否有 429 错误

解决方案:在请求之间增加延迟,或升级套餐。

IP 地址质量

对于住宅代理,低 SR 可能意味着您正在轮换被封锁的 IP 地址。请检查:

  • 有多少百分比的 IP 地址返回 403 Forbidden?
  • 是否有重复的 IP 地址出现?
  • 是否存在模式——某个国家/地区的 IP 可以工作,而另一个不行?

目标服务器的封锁和过滤

错误 429: Too Many Requests

目标服务器检测到来自单个 IP 或总体请求过多。解决方案:

  • 增加延迟: `time.sleep(random.uniform(1, 3))`
  • 使用 IP 轮换: 每个请求使用新的 IP
  • 降低 RPS: 顺序发送请求,而不是并行发送
  • 添加真实的请求头: User-Agent, Referer, Accept-Language

错误 403 Forbidden

服务器阻止了您的 IP(或代理 IP)。这可能是:

  • 地理位置过滤
  • 代理服务黑名单
  • 机器人检测(需要 JavaScript 或 CAPTCHA 处理)

解决方案:使用移动代理或具有 IP 轮换功能的住宅代理。它们更难被检测和封锁。

错误 403: User-Agent 检查

某些服务会拒绝带有可疑 User-Agent 的请求:

import requests
import random

user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36",
    "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15"
]

headers = {
    "User-Agent": random.choice(user_agents),
    "Accept-Language": "en-US,en;q=0.9",
    "Accept": "text/html,application/xhtml+xml",
    "Referer": "https://google.com"
}

response = requests.get(
    "https://target-site.com",
    headers=headers,
    proxies={"http": proxy, "https": proxy},
    timeout=10
)
print(response.status_code)

客户端代码错误

错误的异常处理

一个常见的错误是:代码将连接错误视为失败的请求,但没有尝试重试:

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

# 使用重试机制的正确方法
session = requests.Session()
retry_strategy = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)

try:
    response = session.get(url, proxies=proxies, timeout=10)
except requests.exceptions.RequestException as e:
    print(f"错误: {e}")
    # 记录日志并继续下一个请求

不正确的超时设置

如果超时设置得太短(1-2 秒),慢速的代理将被拒绝:

  • 普通抓取:10–30 秒
  • 移动代理:15–45 秒
  • API 请求:5–10 秒

SSL/TLS 错误

如果使用 `verify=False`,可能会掩盖实际问题。最好是更新证书:

import requests
import certifi

# 正确做法
response = requests.get(
    url,
    proxies=proxies,
    verify=certifi.where(),  # 代替 verify=False
    timeout=15
)

网络问题和超时

连接超时 vs 读取超时

区别很重要:

  • 连接超时 (Connection timeout): 代理无响应(代理或网络问题)
  • 读取超时 (Read timeout): 目标服务器发送数据缓慢(目标服务器问题)
import requests

# timeout = (connection_timeout, read_timeout)
try:
    response = requests.get(
        url,
        proxies=proxies,
        timeout=(5, 15)  # 5秒连接,15秒读取
    )
except requests.exceptions.ConnectTimeout:
    print("代理无响应")
except requests.exceptions.ReadTimeout:
    print("目标服务器响应慢")

DNS 问题

如果目标服务器无法解析域名,那不是代理的问题:

import socket

# 在没有代理的情况下检查 DNS
try:
    ip = socket.gethostbyname("target-site.com")
    print(f"解析成功: {ip}")
except socket.gaierror:
    print("DNS 错误 - 找不到网站")

低 SR 诊断检查清单

  1. 确定基线: 之前的正常 SR 是多少?
  2. 运行隔离测试(使用上述脚本)进行 100 次请求。
  3. 检查日志: 占主导地位的 HTTP 状态码是什么? (407, 429, 403, 超时?)
  4. 如果是 407: 检查用户名/密码和 IP 白名单。
  5. 如果是 429: 在请求之间增加延迟,使用 IP 轮换。
  6. 如果是 403: 检查 User-Agent、Referer,添加真实的请求头。
  7. 如果是超时: 增加 timeout,检查 RPS,使用重试逻辑。
  8. 检查您的代码: 异常处理是否正确,超时设置是否合理。
  9. 检查目标服务器: 不使用代理时是否可访问?
  10. 如果以上都不奏效: 尝试另一种代理类型或更换代理提供商。

快速诊断表

HTTP 状态码 可能的原因 解决方案
407 代理凭据错误 检查用户名/密码,IP 白名单
429 请求过多 增加延迟,使用 IP 轮换
403 IP 被封锁或机器人检测 添加真实的请求头,使用移动代理
Timeout 代理慢或目标服务器过载 增加超时时间,检查 RPS
Connection refused 代理服务器不可达 检查 IP:port,代理状态

总结

低成功率是一个症状,而不是疾病本身。原因可能有很多:从代码中的拼写错误到目标服务器的封锁。系统化的诊断是解决问题的关键:

  1. 检查指标和日志
  2. 隔离问题(代理 vs 目标服务器 vs 您的代码)
  3. 确定错误类型(407, 429, 403, 超时)
  4. 应用相应的解决方案

对于需要高可靠性和高 SR 的任务,我们推荐使用具有 IP 轮换功能的住宅代理。它们更难被检测,且更稳定。请在 proxycove.com 尝试免费测试,并用于您的任务中。