登录
首页 >  文章 >  python教程

PythonRequests库发起请求教程

时间:2026-02-19 19:58:56 100浏览 收藏

Python网络请求的黄金标准——Requests库,以极简直观的API(如requests.get()、requests.post())彻底简化了HTTP通信,同时集成了参数传递、JSON自动序列化、自定义Header、文件上传、会话管理、代理支持、认证机制、SSL控制及完善的异常处理与超时策略等全栈功能;它不仅开箱即用、性能优异、安全可靠,更凭借活跃生态与清晰文档成为开发者提升效率、保障代码健壮性与可维护性的首选利器。

Python代码如何实现网络请求 Python代码使用Requests库的详细教程

Python中实现网络请求,最常用且高效的库无疑是Requests。它以其简洁的API和强大的功能,几乎成为了所有Python开发者进行HTTP通信的首选。无论是简单的GET请求,还是复杂的POST数据提交、文件上传,Requests都能轻松应对,极大地简化了网络编程的复杂度。

Requests库是Python进行网络请求的黄金标准。

首先,你需要确保Requests库已经安装。如果没有,可以通过pip轻松安装: pip install requests

基础GET请求 最常见的操作就是发送GET请求来获取网页内容或API数据。

import requests

try:
    response = requests.get('https://api.github.com/events')
    # 检查响应状态码,如果不是200,会抛出HTTPError
    response.raise_for_status()

    print(f"状态码: {response.status_code}")
    # 获取响应文本内容
    print("响应文本 (部分):", response.text[:200]) 

    # 如果响应是JSON格式,可以直接解析
    data = response.json()
    print("响应JSON (部分):", data[0]['type']) 

except requests.exceptions.HTTPError as errh:
    print(f"HTTP错误: {errh}")
except requests.exceptions.ConnectionError as errc:
    print(f"连接错误: {errc}")
except requests.exceptions.Timeout as errt:
    print(f"超时错误: {errt}")
except requests.exceptions.RequestException as err:
    print(f"其他错误: {err}")

带参数的GET请求 如果你需要向URL传递查询参数,Requests库提供了params参数,它会自动帮你处理URL编码。

import requests

params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://httpbin.org/get', params=params)
print("带参数的GET请求URL:", response.url)
print("带参数的GET请求响应:", response.json()['args'])

基础POST请求 POST请求常用于向服务器提交数据,比如表单数据或JSON数据。

  • 发送表单数据 (form-encoded data): 使用data参数。

    import requests
    
    payload = {'username': 'testuser', 'password': 'testpassword'}
    response = requests.post('https://httpbin.org/post', data=payload)
    print("POST表单数据:", response.json()['form'])
  • 发送JSON数据 (JSON payload): 使用json参数,Requests会自动设置Content-Type: application/json头。

    import requests
    
    json_payload = {'title': 'foo', 'body': 'bar', 'userId': 1}
    response = requests.post('https://jsonplaceholder.typicode.com/posts', json=json_payload)
    print("POST JSON数据状态码:", response.status_code)
    print("POST JSON数据响应:", response.json())

自定义请求头 (Headers) 有时你需要设置特定的HTTP头,比如User-Agent、Authorization等。

import requests

headers = {'User-Agent': 'MyCustomApp/1.0', 'Accept': 'application/json'}
response = requests.get('https://httpbin.org/headers', headers=headers)
print("自定义请求头:", response.json()['headers'])

Requests库的强大之处在于它将这些复杂的HTTP细节封装得非常优雅,让开发者能够专注于业务逻辑而非底层协议。

为什么Requests库是Python网络请求的首选?它有哪些核心优势?

说实话,我用Python做网络请求,几乎没怎么考虑过Requests之外的选项。这并不是因为它功能多到爆炸,而是因为它把“好用”这个词做到了极致。核心优势,我觉得主要体现在几个方面:

首先是它的“人情味”API设计。你看看requests.get()requests.post(),这简直就是口语化的表达,直观得不能再直观了。相比于Python标准库里的urllibhttp.client,那些模块用起来就像是在跟HTTP协议本身打交道,你需要手动处理编码、重定向、会话管理这些细枝末节。Requests则把这些都抽象掉了,你只管告诉它你要做什么,它就帮你搞定。这让代码不仅写起来快,读起来也舒服,维护成本自然就低。

其次是功能全面且开箱即用。你需要的HTTP功能,Requests基本都内置了。比如:

  • 自动处理重定向:默认情况下,Requests会帮你跟踪301/302重定向,省去了手动检查Location头的麻烦。
  • SSL证书验证:默认是开启的,这对于生产环境的安全至关重要,你不需要额外配置。当然,如果你确实需要,也可以轻松关闭。
  • 会话管理 (Sessions):这是一个非常强大的功能。当你需要多次请求同一个网站,并且希望保持Cookie、请求头等状态时,requests.Session()就能派上用场。它不仅能自动维护这些状态,还能利用底层TCP连接的复用,提高性能。
  • 文件上传:通过files参数,上传文件简直不要太方便。
  • 代理支持、认证机制、超时设置等等,这些常用功能都考虑到了,而且接口设计得非常一致和易用。

再来,就是它的活跃社区和丰富文档。遇到问题,几乎都能在Stack Overflow或者官方文档里找到答案。大量的第三方库也围绕Requests构建,进一步扩展了它的能力,比如requests-toolbelt提供了很多高级功能,requests-cache可以缓存请求结果。这种生态支持,也是一个库能否长久发展并成为行业标准的重要因素。

总的来说,Requests库之所以成为首选,就是因为它在易用性、功能性和稳定性之间找到了一个完美的平衡点。它不是最底层的,也不是功能最花哨的,但它绝对是最符合“Pythonic”哲学、最能提升开发效率的网络请求库。

在实际项目中,如何更健壮地处理Requests请求的异常和超时?

在实际的生产环境中,网络请求的健壮性是极其重要的。你不能指望每一次请求都能一帆风顺,网络抖动、服务器宕机、超时、DNS解析失败等等,都是家常便饭。所以,有效地处理异常和超时,是构建可靠应用的基石。

异常处理:捕获Requests的特定异常

Requests库定义了一系列具体的异常类,它们都继承自requests.exceptions.RequestException。这意味着你可以通过捕获RequestException来处理所有Requests相关的错误,或者更精细地捕获特定类型的错误。

import requests

url = "https://nonexistent-domain-for-test.com/api" # 故意设置一个不存在的域名
# url = "https://httpbin.org/status/500" # 测试HTTP错误
# url = "https://httpbin.org/delay/10" # 测试超时

try:
    response = requests.get(url, timeout=5) # 设置5秒超时
    response.raise_for_status() # 如果状态码不是2xx,抛出HTTPError
    print("请求成功:", response.text)

except requests.exceptions.ConnectionError as e:
    print(f"连接错误,可能是DNS解析失败、网络不通或目标服务器拒绝连接: {e}")
    # 可以在这里实现重试逻辑,或者记录日志,通知运维
except requests.exceptions.Timeout as e:
    print(f"请求超时,服务器响应过慢或网络延迟: {e}")
    # 超时可能是暂时的,可以尝试重试
except requests.exceptions.HTTPError as e:
    print(f"HTTP错误,服务器返回了错误状态码(如4xx或5xx): {e.response.status_code} - {e.response.text}")
    # 根据状态码决定是否重试或报警
except requests.exceptions.RequestException as e:
    print(f"发生了Requests库的其他未知错误: {e}")
    # 捕获所有Requests相关的异常
except Exception as e:
    print(f"发生了其他非Requests库的错误: {e}")
    # 捕获其他意料之外的错误

这里有几个关键点:

  1. try...except:这是Python处理异常的标准方式。
  2. timeout参数:这是设置请求超时的核心。它接受一个浮点数或元组。
    • timeout=5:表示整个请求(包括连接和读取)在5秒内没有完成就抛出Timeout异常。
    • timeout=(3, 7):元组形式,第一个值是连接超时(等待建立连接的时间),第二个值是读取超时(等待服务器发送响应的时间)。我个人更倾向于使用元组,因为它能更细粒度地控制超时行为。
  3. response.raise_for_status():这个方法非常有用,它会在收到非2xx状态码(比如404 Not Found, 500 Internal Server Error)时,自动抛出requests.exceptions.HTTPError。这样你就不需要手动检查response.status_code了,代码会更简洁。

重试机制

仅仅捕获异常还不够,很多时候网络问题是暂时的,重试几次就能成功。Requests本身没有内置重试机制,但你可以自己实现,或者使用第三方库,比如requests-retry(基于urllib3Retry策略)。

手动实现一个简单的重试:

import requests
import time

def make_robust_request(url, method='GET', max_retries=3, backoff_factor=0.5, **kwargs):
    for i in range(max_retries + 1):
        try:
            if method.upper() == 'GET':
                response = requests.get(url, **kwargs)
            elif method.upper() == 'POST':
                response = requests.post(url, **kwargs)
            # ... 其他方法

            response.raise_for_status()
            return response
        except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
            if i < max_retries:
                sleep_time = backoff_factor * (2 ** i) # 指数退避
                print(f"请求失败 ({e}),第 {i+1} 次重试,等待 {sleep_time:.2f} 秒...")
                time.sleep(sleep_time)
            else:
                print(f"请求在 {max_retries} 次重试后仍失败: {e}")
                raise # 抛出最后的异常
        except requests.exceptions.HTTPError as e:
            # 对于HTTP错误,通常不建议直接重试,除非你知道这些错误是暂时的(比如503 Service Unavailable)
            print(f"HTTP错误: {e.response.status_code} - {e.response.text}")
            raise # 直接抛出
        except requests.exceptions.RequestException as e:
            print(f"Requests库未知错误: {e}")
            raise # 直接抛出
    return None # 理论上不会执行到这里,因为最后会raise

# 使用示例
try:
    # 模拟一个会超时的请求
    resp = make_robust_request('https://httpbin.org/delay/8', timeout=3, max_retries=2)
    if resp:
        print("最终请求成功!")
except requests.exceptions.RequestException as e:
    print(f"请求最终失败: {e}")

在这个make_robust_request函数中,我加入了指数退避(Exponential Backoff)策略。这意味着每次重试失败后,等待的时间会越来越长,给服务器和网络一个恢复的机会,避免对故障系统造成更大的压力。对于HTTP 5xx错误,通常需要更谨慎地决定是否重试,因为它们可能表示服务器端有更深层次的问题。

除了GET和POST,Requests库还能支持哪些高级HTTP操作,比如文件上传或会话管理?

Requests库远不止GET和POST那么简单,它提供了非常丰富的功能来处理各种复杂的HTTP场景。在实际开发中,这些高级功能经常能帮我们解决很多棘手的问题。

1. 文件上传

上传文件是Web应用中非常常见的需求。Requests通过files参数,让文件上传变得异常简单,无论是单个文件还是多个文件,甚至是从内存中上传文件流。

import requests

# 上传单个文件
# 创建一个虚拟文件用于测试
with open('test_file.txt', 'w') as f:
    f.write('This is a test file for upload.')

url = 'https://httpbin.org/post'
files = {'file': open('test_file.txt', 'rb')} # 'file'是表单字段名
try:
    response = requests.post(url, files=files)
    response.raise_for_status()
    print("文件上传成功:", response.json()['files'])
except requests.exceptions.RequestException as e:
    print(f"文件上传失败: {e}")
finally:
    import os
    os.remove('test_file.txt') # 清理测试文件

# 上传多个文件
# files = {'file1': open('path/to/file1.txt', 'rb'),
#          'file2': open('path/to/file2.txt', 'rb')}
# response = requests.post(url, files=files)

# 从内存中上传文件 (例如,生成图片后直接上传)
# from io import BytesIO
# image_data = BytesIO(b'some_binary_image_data')
# files = {'image': ('my_image.png', image_data, 'image/png')} # (文件名, 文件对象, MIME类型)
# response = requests.post(url, files=files)

注意open('test_file.txt', 'rb')中的'rb'模式,表示以二进制读取模式打开文件,这对于文件上传是必需的。

2. 会话管理 (Sessions)

当你需要与同一个服务器进行多次交互,并且希望保持某些状态(如Cookie、自定义请求头、连接池)时,requests.Session()就显得尤为重要。它能显著提升性能和简化代码。

import requests

# 创建一个会话对象
session = requests.Session()

# 设置会话级别的请求头,之后所有通过这个session发送的请求都会带上这个头
session.headers.update({'User-Agent': 'MySessionApp/1.0', 'X-Custom-Header': 'SessionValue'})

# 第一次请求,服务器可能会设置Cookie
print("--- 第一次请求 ---")
response1 = session.get('https://httpbin.org/cookies/set/sessioncookie/12345')
print("第一次请求的Cookie:", response1.cookies.get('sessioncookie'))

# 第二次请求,会自动带上第一次请求获得的Cookie和会话级的请求头
print("\n--- 第二次请求 ---")
response2 = session.get('https://httpbin.org/cookies')
print("第二次请求发送的Cookie:", response2.json()['cookies'])
print("第二次请求发送的Header:", response2.json()['headers']['X-Custom-Header'])

# 会话结束后,可以关闭会话,释放资源
session.close()

使用Session的好处在于:

  • Cookie持久化:Session对象会自动管理和发送Cookie,模拟浏览器行为。
  • 连接池:Session会维护一个底层TCP连接池,复用连接,减少了每次请求建立新连接的开销,提升了性能。
  • 默认参数:你可以为Session设置默认的请求头、认证信息、代理等,这些设置会应用于所有通过该Session发送的请求,避免重复代码。

3. 认证 (Authentication)

Requests支持多种认证方式,最常见的是HTTP Basic Auth。

import requests
from requests.auth import HTTPBasicAuth

# Basic Auth
response = requests.get('https://httpbin.org/basic-auth/user/pass', auth=HTTPBasicAuth('user', 'pass'))
print("Basic Auth 状态码:", response.status_code)
print("Basic Auth 响应:", response.json())

# 也可以直接传递元组
# response = requests.get('https://httpbin.org/basic-auth/user/pass', auth=('user', 'pass'))

对于更复杂的认证(如OAuth),你可能需要结合第三方库或手动构造认证头。

4. 代理 (Proxies)

当你需要通过代理服务器发送请求时,Requests也提供了简单的配置方式。

import requests

proxies = {
    'http': 'http://10.10.1.10:3128',
    'https': 'http://10.10.1.10:1080',
    # 如果代理需要认证
    # 'http': 'http://user:pass@10.10.1.10:3128',
}

# response = requests.get('http://example.org', proxies=proxies)
# print("通过代理请求成功!")

注意,我这里注释掉了实际的代理请求,因为需要一个真实的代理服务器才能运行。

5. SSL证书验证

Requests默认会验证SSL证书,确保你连接的是合法的服务器。但有时在测试环境或某些特殊情况下,你可能需要禁用它(虽然不推荐在生产环境这样做)。

import requests

# 禁用SSL证书验证 (不推荐用于生产环境)
response = requests.get('https://expired.badssl.com/', verify=False) 
print("禁用SSL验证状态码:", response.status_code)

# 也可以指定一个CA证书文件进行验证
# response = requests.get('https://example.com', verify='/path/to/certfile.pem')

禁用verify参数时,Requests会发出一个警告,提醒你这样做存在安全风险。

这些高级功能,结合Requests本身简洁的API,让它能够应对从简单的数据抓取到复杂的API交互等各种网络请求场景,成为Python开发者的得力工具。

好了,本文到此结束,带大家了解了《PythonRequests库发起请求教程》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多文章知识!

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>