Python爬虫照着浏览器的request header信息抄,为什么运行一段时间还是出现WinError 10060?

很简单的一个爬虫 爬取一个不停变动的数字 显示在屏幕上
请问大家
同一个网址 为什么照着浏览器的 request header 信息抄的 复制到 headers 里
但是爬虫运行一段时间之后还是 10060:[WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。’,))
用的 requestsf
Python爬虫照着浏览器的request header信息抄,为什么运行一段时间还是出现WinError 10060?

15 回复

很简单,不是你把 head 伪装成浏览器,对面就会真傻逼的觉得你就是真人的,识别爬虫的机制多的很,最简单的一种,楼主你的机器人有伪装请求频率吗,人类可做不到机器那么有规律的行为。
再狠一点的,js 里做点手脚,你的爬虫不执行 js,也会被发现


这个问题很常见,核心原因是你只复制了静态的请求头,但忽略了浏览器请求中的动态行为和网络环境差异。

浏览器请求是“活的”,它自动处理了连接保持、Cookie管理、重试机制和超时设置。而你的爬虫代码如果只是简单复制headers,然后用requests.get()去请求,就缺少了这些容错机制。当目标服务器响应慢、网络不稳定或者有反爬策略时,固定的超时设置很容易导致连接超时(WinError 10060)。

要解决这个问题,关键是给你的请求增加健壮性处理。下面是一个改进后的代码示例,它设置了合理的超时、自动重试,并模拟了更真实的浏览器会话:

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

def create_robust_session():
    """
    创建一个配置了重试和超时机制的稳健requests会话。
    """
    session = requests.Session()

    # 1. 设置重试策略
    retry_strategy = Retry(
        total=3,  # 总共重试3次(包括第一次请求)
        backoff_factor=1,  # 重试等待时间间隔:1, 2, 4 秒
        status_forcelist=[429, 500, 502, 503, 504],  # 遇到这些HTTP状态码会重试
        allowed_methods=["GET", "POST"]  # 只对GET和POST方法重试
    )
    adapter = HTTPAdapter(max_retries=retry_strategy)
    session.mount("http://", adapter)
    session.mount("https://", adapter)

    # 2. 设置公共请求头(把你从浏览器复制的headers放这里)
    session.headers.update({
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
        # ... 其他你需要的headers
    })

    return session

def fetch_url_with_retry(url, session=None):
    """
    使用稳健的会话获取URL,包含自定义超时和异常处理。
    """
    if session is None:
        session = create_robust_session()

    try:
        # 3. 设置合理的超时时间(连接超时和读取超时分开设置)
        response = session.get(url, timeout=(5, 15))  # (连接超时5秒, 读取超时15秒)
        response.raise_for_status()  # 如果HTTP状态码不是200,会抛出HTTPError
        return response

    except requests.exceptions.Timeout:
        print(f"请求超时: {url}")
        # 这里可以加入更复杂的超时处理逻辑,比如记录日志、更换代理等
        return None
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {url}, 错误: {e}")
        return None

# 使用示例
if __name__ == "__main__":
    url = "https://example.com"
    session = create_robust_session()

    for i in range(10):
        print(f"第{i+1}次尝试...")
        resp = fetch_url_with_retry(url, session)

        if resp and resp.status_code == 200:
            print("成功获取页面")
            # 处理你的响应内容...
            break
        else:
            print("获取失败,稍后重试...")
            time.sleep(2)  # 失败后等待一段时间再试

代码关键点解释:

  1. 会话(Session):使用requests.Session()可以保持连接和Cookie,比单次请求更高效。
  2. 重试机制:通过urllib3RetryHTTPAdapter,让代码在遇到临时性错误(如网络波动、服务器繁忙)时自动重试。
  3. 超时设置timeout=(5, 15)设置了连接超时(5秒)和读取超时(15秒),防止请求无限挂起。
  4. 异常处理:捕获Timeout和其他RequestException,让程序在遇到错误时不会崩溃,并能进行后续处理(如记录、重试)。

总结建议:别只抄headers,要把浏览器的“韧性”也抄过来。

10060 是超时,跟 header 没关系

我把 timeout 设置成 60 秒了 但是要获取的那个数字几乎每秒都在变动 我估计对方发现这个请求不是真人 故不选择响应了。。。


有啊 time.sleep(0.2) 我把这个数字改大一点试一下吧 。
因为要爬取的数字类似股票价格变化,每秒都在 变化好几次,原网页的数字应该是动态加载出来的,我按 f12 获取那个真实的地址了然后 request 请求了网址。我不知道用 requsts 直接请求真实地址的方式跟浏览器动态加载原网页出来的效果,对方能不能识别出来。

一般都有反爬虫策略吧?比如你的频率太快了。建议上代理,或者用分布式的爬虫。

应该是反爬虫策略。你一秒钟按一次 F5,应该也一样会被封禁

现在改成频率一秒请求下那个动态加载出来的数字的真实地址。算快吗?
但是那个网页的数字一秒钟要变化 1 到 3 次,是不是因为爬虫伪装的浏览器请求的的频率跟原装的不一致导致的。

动态加载网页 ,浏览器没刷新
然后 f12 浏览器在不停的发送间隔时间不等的数字请求 反而不被禁,但是浏览器为什么会发送间隔时间随机的请求呢?难道是因为对方服务器等这个数字变化了再给浏览器发送的数据?
是不是因为这个模拟浏览器请求频率跟这个间隔时间频率不一定导致被对方发现的。

10060 超时是 socket 层面错误,并不是 web service 作出“对抗”响应的,它更多是网络原因造成的

所以终极方案还是 chrome 或者 selenium 了呗?

很明显,这是 js 轮询,对方在 js 里肯定有某些算法识别的,你没对上就屏蔽你,你遇上了反爬虫而已

不需要 web service 层,写个延时脚本直接在反向代理那把你干了就行

现在基本反爬虫已经是各大网站的标配了,
有兴趣的可以看看这里:
https://zhuanlan.zhihu.com/data-factory
楼主很明显缺乏一些基本概念,还是不要尝试这种关键数据,我说个很简单的方法,如果你要求不高的话,对这个场景最合适的做法是:自己写油猴脚本配合 chrome 抓取,保证没问题;或者上无头浏览器;研究 js 是不归路,不是对 js 造诣很深的人,都不建议去整,混淆就能玩死你,上个 eval 就能让你欲仙欲死,等你好不容易研究出来了人家改个方式你又完蛋,js 反反爬虫是逆向破解,最大的好处是你的 js 水平会曾指数级上升

嗯 谢谢 这就去看看

回到顶部