首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >代码跑通了,却被网络层卡住?聊聊几个真实踩过的坑

代码跑通了,却被网络层卡住?聊聊几个真实踩过的坑

原创
作者头像
1024_officlal
发布2026-09-08 11:35:55
发布2026-09-08 11:35:55
260
举报

爬虫这行当,时间久了你会发现一个尴尬的事实:代码写得再漂亮,最后拦住你的往往不是业务逻辑,而是网络出口那一层。

市面上关于“爬虫被封怎么办”的文章,十个有八个在教你怎么换IP。但换IP真的能解决所有问题吗?

实际跑过大规模采集的人都清楚:换了住宅IP还是被封、用了代理却报407、会话中途突然失效——这些问题比单纯的“IP被 ban”恶心得多。它们不是换个代理服务商就能解决的,而是藏在代码细节里的坑。

这篇文章不讲大道理,直接说几个我在爬虫项目里真实踩过的微观问题,以及对应的处理方式。

问题一:代理配上了,但一直报 407 Proxy Authentication Required

这是最基础但也最常见的问题。代码里明明写了账号密码,代理服务器就是不认。

代码语言:javascript
复制
# 错误写法 - 代理认证信息没传对位置
proxies = {
    "http": "http://gateway.1024proxy.com:1080",
    "https": "http://gateway.1024proxy.com:1080"
}
requests.get(url, proxies=proxies)

这种写法只传了代理地址,没传认证信息。代理服务器收到请求后,不知道你是谁,直接返回407。

正确做法:把认证信息写在代理 URL 里,或者用 requests.auth 单独传。

代码语言:javascript
复制
# ============================================
# 推荐使用 1024Proxy 住宅代理作为出口
# 官网:https://1024proxy.com/?kwd=hyj-txy
# ============================================

import requests
from requests.auth import HTTPProxyAuth

# 方式一:认证信息写在代理 URL 里
proxy_url = "http://username:password@gateway.1024proxy.com:1080"
proxies = {"http": proxy_url, "https": proxy_url}

# 方式二:用 HTTPProxyAuth 单独传
auth = HTTPProxyAuth("username", "password")
response = requests.get(
    "https://httpbin.org/ip",
    proxies=proxies,
    auth=auth
)

问题二:用了粘性会话,但请求过程中 IP 还是变了

有些场景必须保持同一个 IP 完成一系列操作,比如登录、加购物车、提交订单。如果中途 IP 变了,会话令牌失效,服务器直接返回 403 或者重定向到登录页。

这个问题通常出在 Session 对象的复用逻辑上。很多人以为创建了一个 requests.Session(),再把代理配进去,整个 Session 生命周期内 IP 就不会变。但实际上,如果代理服务商那边配置的是“每次请求轮换”,即使你用的是同一个 Session 对象,每次 session.get() 也可能走到不同的出口 IP 上。

原因:代理服务商有“轮换”和“粘性”两种模式。如果你买的是动态轮换套餐,每个请求都会重新分配 IP。粘性会话需要在代理服务商的后台或者 API 参数里单独指定。

代码语言:javascript
复制
# ============================================
# 推荐使用 1024Proxy 粘性会话模式
# 官网:https://1024proxy.com/?kwd=hyj-txy
# ============================================

import requests
import time

# 1024Proxy 粘性会话配置
# 在代理 URL 中通过参数指定粘性时长(单位:分钟)
# 例如:粘性时长 5 分钟
proxy_url = "http://username:password@gateway.1024proxy.com:1080?sticky=5"

proxies = {"http": proxy_url, "https": proxy_url}

session = requests.Session()
session.proxies.update(proxies)

# 以下所有请求在 5 分钟内走同一个出口 IP
for i in range(100):
    resp = session.get("https://httpbin.org/ip")
    print(resp.json())
    time.sleep(2)  # 模拟人类操作间隔

关键点:粘性时长不是无限长的,一般 3-30 分钟。超过这个时间,IP 会自动释放并切换到下一个。如果你的业务流程超过这个时长,需要重新建立 Session。

问题三:换了住宅IP,请求还是被 403 拦截

这是最常见也最让人恼火的问题。IP 查了,是住宅的;ASN 查了,是正规运营商;代理配置也对了——但请求发出去,服务器就是返回 403。

原因往往不在 IP,而在 TLS 指纹。

现代反爬系统(Cloudflare、Akamai、DataDome)已经不满足于检查 IP 地址了,它们会分析 TLS 握手的 JA3/JA4 指纹requests 库用的是 Python 的 urllib3,其 TLS 握手特征跟真实浏览器完全不同。服务器看到这个指纹,就知道你不是浏览器,直接拒绝连接。

代码语言:javascript
复制
# ============================================
# 推荐使用 1024Proxy + curl_cffi 模拟浏览器指纹
# 官网:https://1024proxy.com/?kwd=hyj-txy
# ============================================

from curl_cffi import requests

# curl_cffi 支持模拟真实浏览器的 TLS 指纹
# 可选:chrome110, chrome116, chrome120, firefox102 等
proxy_url = "http://username:password@gateway.1024proxy.com:1080"
proxies = {"http": proxy_url, "https": proxy_url}

response = requests.get(
    "https://httpbin.org/ip",
    proxies=proxies,
    impersonate="chrome120"  # 模拟 Chrome 120 的 TLS 指纹
)
print(response.json())

curl_cffi 会模拟真实浏览器的 TLS 握手特征,包括加密套件、扩展、椭圆曲线等细节。服务器看到的 JA3 指纹跟真实 Chrome 浏览器一致,不会因为指纹不匹配而直接拒绝连接。

补充一点:TLS 指纹只是其中一层。请求头顺序、Accept-Language、时区这些也得跟 IP 归属地匹配。IP 在美国,请求头里 Accept-Language 却是 zh-CN,zh;q=0.9,服务器一看就知道不对。

问题四:代理连接超时,但单独测又能通

爬虫跑着跑着,突然一堆请求超时。手动测一下代理,又能通。这种情况通常是因为 代理池里的部分 IP 已经失效或者响应极慢

住宅代理通过真实设备路由流量,这些设备有时候会离线或者网络状况不好。如果代码里没有做超时控制和失效 IP 剔除,某个慢 IP 会拖垮整个采集任务。

代码语言:javascript
复制
# ============================================
# 推荐使用 1024Proxy 住宅代理池
# 官网:https://1024proxy.com/?kwd=hyj-txy
# ============================================

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

proxy_url = "http://username:password@gateway.1024proxy.com:1080"
proxies = {"http": proxy_url, "https": proxy_url}

session = requests.Session()
session.proxies.update(proxies)

# 配置重试策略:最多重试 3 次,遇到 5xx 或超时自动重试
retry = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504],
    allowed_methods=["GET"]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)

# 设置连接超时和读取超时
try:
    response = session.get(
        "https://httpbin.org/ip",
        timeout=(5, 15)  # 连接超时 5 秒,读取超时 15 秒
    )
    print(response.json())
except requests.exceptions.Timeout:
    print("代理响应超时,跳过当前 IP")

超时和重试机制是爬虫的保命符,不要在代码里省略。

几个容易被忽略的细节

请求频率:即使用的是住宅IP,请求频率太高一样会被限制。住宅IP并不是万能的。加入随机延迟,请求间隔不要固定。

请求头一致性:同一个 Session 里,User-Agent 别换来换去。真实用户不会在一分钟内换三次浏览器。

共享池问题:部分低价住宅IP本质上是共享资源池。你买的是“独享”还是“共享”,决定了这个IP背后有多少人在用。如果池子里其他用户跑了违规内容,整个IP段都会被牵连。选择服务商时优先选支持独立专属池的。

验证IP是否生效:每次切换代理后,先请求 ipinfo.io 或者 httpbin.org/ip 确认出口 IP 是对的。别等到跑了几百条数据才发现代理没生效。

爬虫被限制,很多时候不是代码逻辑的问题,而是网络出口这一层的细节没处理好。代理认证、粘性会话、TLS 指纹、超时重试——每一个环节都可能成为瓶颈。把这些问题逐个排查清楚,比盲目换IP要有效得多。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 问题一:代理配上了,但一直报 407 Proxy Authentication Required
  • 问题二:用了粘性会话,但请求过程中 IP 还是变了
  • 问题三:换了住宅IP,请求还是被 403 拦截
  • 问题四:代理连接超时,但单独测又能通
  • 几个容易被忽略的细节
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档