You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用requests.get请求HTTP简易服务器返回404,但wget可成功获取

解决requests.get返回404但wget能成功获取本地文件的问题

老哥,你遇到的这个情况我之前也碰到过——同一台机器上,wget --no-proxy http://localhost:8000/sample.tar能正常拿到文件,Python的requests库请求同一个URL却返回404,大概率是这几个容易忽略的细节在搞鬼,我给你梳理排查方向:

1. requests默认走了代理,而wget被你强制关了代理

你用wget的时候加了--no-proxy,但requests会默认读取系统的代理配置(比如环境变量里的HTTP_PROXY、HTTPS_PROXY),哪怕是localhost的请求也可能被错误地转发到代理服务器,导致你的本地文件服务器根本没收到请求,自然返回404。

解决办法很简单,在requests.get里显式关闭代理:

def get(url):
    if url == '':
        raise ValueError('Empty Fetch URL')
    try:
        # 显式禁用所有代理
        response = requests.get(url, proxies={"http": None, "https": None})
        response.raise_for_status()  # 主动抛出HTTP错误,方便排查
        return response.content
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")

或者你也可以在运行Python脚本前设置环境变量:export NO_PROXY=localhost,127.0.0.1(Linux/macOS),或者set NO_PROXY=localhost,127.0.0.1(Windows),让requests自动跳过本地地址的代理。

2. 代码里的URL存在隐藏的不一致

有时候代码里的URL可能不小心多了空格、换行符,或者大小写差异(虽然HTTP URL通常不区分大小写,但有些简易服务器可能做了严格匹配)。比如你代码里的URL是不是写成了http://localhost:8000/sample.tar (末尾多了空格),或者http://localhost:8000/Sample.tar?

你可以在代码里打印URL的原始格式,对比wget里的地址:

def get(url):
    if url == '':
        raise ValueError('Empty Fetch URL')
    # 用repr()可以显示出隐藏的字符,比如空格、换行
    print(f"当前请求的URL: {repr(url)}")
    try:
        response = requests.get(url, proxies={"http": None, "https": None})
        # ... 后续代码

3. requests的默认请求头被服务器拦截

有些简易HTTP服务器(比如Python自带的python -m http.server)对请求头兼容性很好,但偶尔requests默认的User-Agent或者其他头可能触发了服务器的某种规则(虽然概率很低,但值得排查)。

你可以模拟wget的请求头试试,wget的默认User-Agent格式是Wget/[版本号],你可以用wget --version查看自己的版本,然后在requests里设置:

def get(url):
    if url == '':
        raise ValueError('Empty Fetch URL')
    try:
        # 模拟wget的请求头
        headers = {'User-Agent': 'Wget/1.21.3'}  # 换成你的wget版本
        response = requests.get(url, headers=headers, proxies={"http": None, "https": None})
        response.raise_for_status()
        return response.content
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")

4. 查看服务器访问日志,对比请求差异

如果上面的方法都没用,你可以看看本地HTTP服务器的访问日志(比如Python自带的http.server会在控制台打印每一条请求),对比requests和wget的请求细节:

  • 请求路径是否一致?
  • HTTP版本是否相同?(requests默认用HTTP/1.1,wget可能用HTTP/1.0)
  • 请求方法是不是都是GET?

如果发现是HTTP版本的问题,你可以让requests强制使用HTTP/1.0:

from requests.adapters import HTTPAdapter
from urllib3.poolmanager import PoolManager

class HTTP10Adapter(HTTPAdapter):
    def init_poolmanager(self, connections, maxsize, block=False):
        self.poolmanager = PoolManager(
            num_pools=connections, maxsize=maxsize,
            block=block,
            _http_vsn=10,  # 设置HTTP版本为1.0
            _http_vsn_str='HTTP/1.0'
        )

def get(url):
    if url == '':
        raise ValueError('Empty Fetch URL')
    try:
        session = requests.Session()
        session.mount('http://', HTTP10Adapter())
        response = session.get(url, proxies={"http": None, "https": None})
        response.raise_for_status()
        return response.content
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {e}")

按这个顺序排查,应该能很快找到问题所在!

内容的提问来源于stack exchange,提问作者hellojoshhhy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:25:56