Python requests模块详解

简介

Python 的 requests 模块是一个流行的第三方库,用于发送HTTP请求。它提供了一组简洁且易于使用的API,使得在Python中进行网络通信变得更加简单和灵活。

1. 基本概念

  • 定义:HTTP(Hypertext Transfer Protocol)是基于客户端–服务器模型的协议,通过 URL 定位资源,用请求/响应方式传输。

  • 主要作用

    1. 传输数据:支持 HTML、图片、视频、音频等类型的数据传输。

    2. 资源定位:URL 唯一标识资源。

    3. 通信无状态:每个请求独立,服务器不自动保存状态。

    4. 安全性:原始 HTTP 明文传输;即可升级使用 HTTPS(SSL/TLS)。

  • 请求组成

    • 方法(GET、POST、PUT、DELETE 等)

    • 头部(如 User-AgentContent-Type

    • 请求体(可选,传递表单、JSON、文件等)

2. 常用 HTTP 方法对比 👇

方法 用途 参数位置 安全性 幂等性 缓存支持
GET 获取资源 URL 查询串 低(明文) 支持
POST 提交数据 / 创建/修改资源 请求体 较高 通常不支持
PUT 更新/替换资源 请求体 同 POST 通常不支持
DELETE 删除资源 URL/请求体 同 POST 通常不支持

2.1. GET 请求

  • GET请求是HTTP协议中的一种请求方法,用于从服务器获取资源。它是最常见和最简单的请求方法之一。

  • GET请求中的请求参数会暴露在URL中,因此,不应将敏感信息通过GET请求传递。对于传输敏感信息(例如:用户、密码)或需要修改服务器上资源状态的请求,应使用POST请求或其他更安全的请求方法。

get 请求的特点

  • 请求参数通过URL中的查询字符串传递,如:http://www.baidu.com/path?param1=value1&param2=value2

  • GET请求对请求参数的长度有限制,因为URL的长度是有限制的,不适合传输大量的数据。

  • GET请求是幂等的,即多次重复发送同样的GET请求,不会对服务器产生副作用,也不会修改服务器上的资源状态。

  • GET请求可以被缓存,如果相同的GET请求被发送多次,中间的请求可以通过缓存直接返回响应结果。

get 请求的优点

  1. 简单和直观:GET请求是HTTP协议中最简单的请求方法,只需要通过URL进行请求信息的传递,易于理解和实现。

  2. 可缓存:GET请求可以被缓存,如果相同的GET请求被重复发送,中间的请求可以通过缓存直接返回响应结果,减少了服务器的负载和网络传输时间。

  3. 可书签化:由于GET请求的参数附加在URL中,因此可以将带有GET请求的URL添加到书签中,方便用户保存和分享特定的资源。

  4. 可见性:GET请求的参数和请求信息都会暴露在URL中,可以直观地看到请求的内容,方便调试和问题排查。

get 请求的缺点

  1. 长度限制:GET请求的请求参数通过URL的查询字符串传递,URL的长度是有限制的,所以对于大量数据的传输不合适,存在长度限制问题。

  2. 安全性问题:GET请求中的请求参数暴露在URL中,可能被其他人在网络传输过程中截获或记录,存在安全风险。敏感信息(如密码)不应通过GET请求传递。

  3. 副作用问题:GET请求属于幂等请求,即多次发送同样的GET请求不会对服务器产生副作用。但对于涉及修改服务器资源状态或产生其他副作用的请求(如增、删、改等操作),不应该使用GET请求。

2.2. POST 请求

  • POST请求是HTTP协议中的一种请求方法,用于向服务器提交数据,并请求服务器处理该数据。与GET请求相比,POST请求常用于发送较大量的数据、修改服务器上的资源状态以及进行敏感操作等。

  • POST请求不仅可以传输表单数据,也可以传输其他类型的数据,如JSON、XML等。使用POST请求时,需要根据具体的场景和需求,将数据格式化和编码成对应的请求体数据类型。

port 请求的特点

  1. 数据传输较安全:相对于GET请求将数据暴露在URL中,POST请求将数据放在消息体中发送,对于敏感信息更为安全。

  2. 请求参数长度无限制:POST请求中的参数和数据不会受到URL长度限制,能够传输较大量的数据。

  3. 不可缓存:由于POST请求需要向服务器提交数据,每次请求的数据都可能不同,所以大部分情况下不能被缓存,需要实时重新请求。

  4. 非幂等性:POST请求可能对服务器资源产生副作用,即每次发送相同的POST请求,可能会对服务器资源状态进行修改。

port 请求的优点

  1. 数据安全性更高:相对于GET请求,POST请求将数据放在请求的消息体中传输,而不是直接附加在URL中,因此对于敏感信息的传输更加安全,减少了数据被恶意拦截或篡改的风险。

  2. 容量大小无限制:POST请求传输的数据没有URL长度限制,可以传输较大的数据量,适合上传文件或传输大量文本数据。

  3. 更好的请求语义:POST请求用于向服务器提交数据并请求处理,适合于对服务器资源进行修改、创建等操作,具有更好的请求语义。使用POST请求可以清晰地表达意图,使服务器能够更好地处理和响应请求。

  4. 支持多种数据格式:POST请求可以使用不同的Content-Type来指定数据格式,可以传输多种类型的数据,如表单数据、JSON数据、XML数据等,具有更大的灵活性。

post 请求的缺点

  1. 非幂等性:POST请求可能对服务器资源产生副作用,即每次发送相同的POST请求,都可能会对服务器资源状态进行修改,而不仅仅是获取资源。这意味着相同的POST请求不能重复执行,可能会导致不可预料的结果。

  2. 不可缓存:由于POST请求中往往包含了对服务器资源的修改,为了保证数据的一致性,POST请求通常不能被缓存,需要实时重新请求,增加了服务器的负载和网络传输时间。

  3. 请求复杂度相对较高:相对于GET请求,POST请求在构造和发送上相对复杂一些,需要将数据放入请求的消息体中,并设置合适的Content-Type、Content-Length等请求头部信息。

2.3. get 和 post 的区别

  • GET请求适用于获取资源、查询或浏览数据等操作,传输的数据量较小且不涉及敏感信息。

  • POST请求适用于向服务器提交数据、修改资源状态等操作,支持传输较大量的数据和敏感信息的安全传输。

参数位置和传输方式

  • GET请求:参数通过URL的查询字符串传递,附加在URL的末尾,以?开头,多个参数之间使用&分隔,例如:http://www.baidu.com/path?param1=value1&param2=value2。数据可以通过URL进行传输,也可以通过请求头的字段进行传输。

  • POST请求:参数和数据放在请求的消息体中,通过请求头部的Content-Type字段来指定数据的类型,常见的有application/x-www-form-urlencoded、multipart/form-data、application/json等。

数据传输安全性

  • GET请求:参数和数据暴露在URL中,容易被拦截、篡改或记录,不适合传输敏感信息。

  • POST请求:参数和数据放在请求的消息体中传输,对于敏感信息的安全性更高。

请求语义和副作用

  • GET请求:主要用于从服务器获取资源,获取数据的语义明确,是幂等的,多次请求结果相同,不会对服务器产生副作用。

  • POST请求:主要用于向服务器提交数据,请求可能对服务器产生副作用,常用于修改、创建资源等操作,不具备幂等性。

URL长度限制

  • GET请求:由于参数在URL中传递,URL的长度存在限制(不同浏览器和服务器对URL长度的限制不同),不适合传输大量数据。

  • POST请求:没有URL长度限制,可以传输较大量的数据。

缓存

  • GET请求:可以被缓存,如果相同的GET请求被重复发送,中间的请求可以通过缓存直接返回响应结果,减少了服务器的负载和网络传输时间。

  • POST请求:通常不会被缓存,因为POST请求可能对服务器资源产生副作用,需要实时重新请求。

3. 使用 requests 发送请求

3.1 GET 请求

语法

requests.get(url           #必选参数,指定URL地址    
            params=None   #可选参数,用于指定查询参数,可以是一个字典或一个字符串。    
            **kwargs      #可选参数,用于传递其他参数,例如请求头、超时时间等。) 
            **kwargs 可以是:    headers:设置请求头信息    timeout:设置请求的超时时间(单位:秒)

发送一个简单的 get 请求

import requests 
# 发送get请求
response = requests.get('https://www.baidu.com/') 
# 打印状态码
print(response) 
# 打印内容
print(response.text)

发送带查询参数的 get 请求

params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://www.baidu.com/', params=params)

发送GET请求并加入其他参数(设置请求头和请求超时时间)

headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get('https://www.baidu.com/', headers=headers, timeout=5)

3.2. 发送 post 请求

语法

requests.post(url            #必选参数,指定URL地址。    
              data=None      #可选参数,传递表单数据。可以是一个字典、字符串或二进制数据。   
              json=None      #可选参数,传递JSON数据。将自动将数据编码为JSON格式并设置请求头部的Content-Type为application/json。
              headers=None   #可选参数,指定HTTP请求的头部信息。可以通过⭐字典⭐形式传递。    
              cookies=None   #可选参数,传递Cookie信息。可以是字典或CookieJar对象。    
              auth=None      #可选参数,用于身份验证,可以是身份验证相关的对象,如HTTPBasicAuth或HTTPDigestAuth等。    
              timeout=None   #可选参数,设置请求的超时时间(单位:秒)    
              allow_redirects  #可选参数,用于设置是否允许重定向(默认True)。    
              **kwargs       #可选参数,用于传递其他参数,例如proxies、verify(SSL验证)等。)

发送一个简单的 post 请求

import requests 
# 发送post请求
response = requests.post('https://www.baidu.com/') 
# 打印状态码
print(response) 
# 打印内容
print(response.text)

发送JSON数据的POST请求

import json 
url = 'https://www.baidu.com/'
data = {'key': 'value'}
headers = {'Content-Type': 'application/json'}
response = requests.post(url, json=json.dumps(data), headers=headers)

发送带有请求头和超时时间的POST请求

url = 'https://www.baidu.com/'
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.post(url , headers=headers, timeout=5)

送带有身份验证的POST请求

from requests.auth import HTTPBasicAuth 
url = 'https://www.baidu.com/'
auth = HTTPBasicAuth('username', 'password')
response = requests.post(url, auth=auth)

发送带有Cookie的POST请求

url = 'https://www.baidu.com/'
cookies = {'session_id': '123456'}
response = requests.post(url, cookies=cookies)

3.3. 发送 delete 请求

语法

requests.delete(
    url            #必选参数,指定URL地址。
    params=None    #可选参数,传递URL查询参数。可以是一个字典或字符串。
    headers=None   #可选参数,指定HTTP请求的头部信息。可以通过字典形式传递。
    cookies=None   #可选参数,传递Cookie信息。可以是字典或CookieJar对象。
    auth=None      #可选参数,用于身份验证,可以是身份验证相关的对象,如HTTPBasicAuth或HTTPDigestAuth等。
    timeout=None   #可选参数,设置请求的超时时间(单位:秒)
    allow_redirects  #可选参数,用于设置是否允许重定向(默认True)。
    **kwargs       #可选参数,用于传递其他参数,例如proxies、verify(SSL验证)等。
)

发送一个简单的 delete 请求

# 发送delete请求
response = requests.delete('https://www.baidu.com/')
 
# 打印状态码
print(response)
 
# 打印内容
print(response.text)

3.4. 发送 put 请求

语法

requests.put(
    url            #必选参数,指定URL地址。
    data=None      #可选参数,传递表单数据。可以是一个字典、字符串或二进制数据。
    json=None      #可选参数,传递JSON数据。将自动将数据编码为JSON格式并设置请求头部的Content-Type为application/json。
    headers=None   #可选参数,指定HTTP请求的头部信息。可以通过字典形式传递。
    cookies=None   #可选参数,传递Cookie信息。可以是字典或CookieJar对象。
    auth=None      #可选参数,用于身份验证,可以是身份验证相关的对象,如HTTPBasicAuth或HTTPDigestAuth等。
    timeout=None   #可选参数,设置请求的超时时间(单位:秒)
    allow_redirects  #可选参数,用于设置是否允许重定向(默认True)。
    **kwargs       #可选参数,用于传递其他参数,例如proxies、verify(SSL验证)等。
)

发送一个简单的 put 请求

# 发送put请求
response = requests.put('https://www.baidu.com/')
 
# 打印状态码
print(response)
 
# 打印内容
print(response.text)

4. 处理响应

4.1. 获取响应内容

  • 语法
response.text    #以字符串形式返回响应内容。
response.content #以字节形式返回响应内容。
response.json()  #以JSON解析并返回响应内容。如果响应内容不是有效的JSON格式,则会抛出JSONDecodeError异常。
  • 示例
response = requests.get('https://www.baidu.com/')
print(response.text)     # 以 "字符串" 形式返回响应内容
print(response.content)  # 以 "字节" 形式返回响应内容
print(response.json())   # 以 "JSON" 形式返回响应内容(如果响应内容不是有效的JSON格式,则会抛出JSONDecodeError异常。)

4.2. 获取响应状态

  • 语法
response.status_code  #返回响应的状态码。
response.ok           #返回布尔值,表示请求是否成功(2xx响应码)。response.raise_for_status()  #如果响应状态码表明请求不成功,则抛出HTTPError异常。
  • 示例
response = requests.get('https://www.baidu.com/')
print(response.status_code)  # 获取响应的 "状态码"
print(response.ok)  # 获取响应的 "状态码的布尔值"
print(response.raise_for_status())  # "状态码"异常则抛出 "ConnectionError" 异常。

4.3. 获取响应头部信息

  • 语法
response.headers  #返回响应头部的字典形式。
response.headers['header_name']  #返回指定头部字段的值。
  • 示例
response = requests.get('https://www.baidu.com/')
print(response.headers)         # 以 "字典形式" 返回响应头部的全部信息
print(response.headers['Date']) # 返回指定头部 "字段的值"

4.4. 处理重定向

  • 语法
response.history  #返回一个包含重定向历史的列表,每个元素是一个Response对象。
response.url      #返回最终响应的URL。
  • 示例
response = requests.get('https://www.baidu.com/')
print(response.history)  # 返回一个包含 "重定向历史" 的列表 
print(response.url)  # 返回最终响应的 "URL" 

4.5. 获取其他响应信息

语法

response.encoding   #返回响应使用的字符编码。
response.cookies    #返回响应的Cookies信息,可以进行进一步操作。
  • 示例
response = requests.get('https://www.baidu.com/')
print(response.encoding) # 返回响应的 "字符编码"
print(response.cookies)  # 返回响应的 "cookies信息" 

4.6. 指定内容字符集

# 获取结果
response = requests.get('https://www.baidu.com/') 
# 按内容展示
html = response.text 
# 指定内容的字符集
html = response.content.decode('utf-8') 
# 输出结果
print(html)

5.1. 会话管理

  • 发送多个相关请求时,使用会话(Session)对象来管理这些请求,以便在多个请求之间共享状态、Cookie和身份验证等信息。

举例

import requests
 
# 创建会话对象
session = requests.Session()
 
# 设置会话级别的头部信息(可选)
session.headers.update({'User-Agent': 'Mozilla/5.0'})
 
# 第一个请求(使用post请求登录)
response1 = session.post('http://xxx.com/login', data=login_data)
 
# 第二个请求(登录以后的其他操作1)
response2 = session.get('http://xxx.com/xxx1')
 
# 第三个请求(登录以后的其他操作2)
response3 = session.get('http://xxx.com/xxx2')
 
# 关闭会话
session.close()
  • 创建一个会话对象后,身份信息和cookie都可以共享,适用于多个相关联的请求。

使用会话对象的优点

  1. 自动管理Cookie:会话对象会自动在请求中发送和更新Cookie信息,无需手动处理。

  2. 共享会话级别信息:会话对象可用于共享头部信息、身份验证等。这避免了在每个请求中单独设置这些信息的麻烦。

  3. 连接重用:会话对象会自动重用连接,提高请求性能。

5.2. Cookie 操作

1、添加 cookie

import requests 
url = 'http://xxx.com'
cookies = {'name': 'value'} # 请求中添加cookie值
response = requests.get(url, cookies=cookies)

2、获取 cookie 值

import requests 
response = requests.get('https://www.baidu.com/') 
# 直接打印cookie全部信息
print(response.cookies) 
# 通过name和value获取名称和值
for cookie in response.cookies:
    print(cookie.name, cookie.value)

3、删除 cookie

import requests 
response = requests.get('https://www.baidu.com/') 
# 删除名称为'BDORZ'的 
Cookieresponse.cookies.pop('BDORZ') 
# 删除所有
Cookieresponse.cookies.clear()

4、添加 cookie 到会话

import requests 
# 创建一个会话
session = requests.Session() 
# 添加Cookie到会话
cookies = {'name': 'value'}
session.cookies.update(cookies) 
# 使用包含Cookie的会话发送请求
response = session.get(url)   
# 清除所有
Cookiesession.cookies.clear()  

6. 异常处理

6.1. 捕获所有异常

  • RequestException 是所有异常的基类,可以用于捕获所有的异常情况。当发生网络请求错误时,例如连接超时、DNS解析失败等,可以使用该异常来捕获并处理。
requests.exceptions.RequestException

示例

import requests
from requests.exceptions import RequestException 
try:
    response = requests.get(url)
    print('响应正常,执行下一步')
except RequestException as e:
    print("请求发生异常:", str(e))

6.2. 捕获状态码异常

  • HTTPError 表示HTTP错误状态码(4xx或5xx)的响应。可以使用响应对象的.raise_for_status()方法来引发该异常。
requests.exceptions.HTTPError

示例

import requests
from requests.exceptions import HTTPError 
try:
    response = requests.get(url)
    response.raise_for_status()
    print('响应正常,执行下一步')
except HTTPError as e:
    print("HTTP错误:", str(e))

6.3. 捕获连接失败异常

  • ConnectionError 用于捕获请求连接失败的异常,例如:无法连接到目标服务器,或者网络连接中断。
requests.exceptions.ConnectionError

示例

import requests
from requests.exceptions import ConnectionError 
try:
    response = requests.get(url)
    print('响应正常,执行下一步') 
except ConnectionError as e:
    print("连接错误:", str(e))

6 .4. 捕获请求超时异常

Timeout 用于捕获请求超时的异常

requests.exceptions.Timeout

示例

import requests
from requests.exceptions import Timeout 
try:
    response = requests.get(url, timeout=5)
    print('响应正常,执行下一步') 
except Timeout as e:
    print("请求超时:", str(e))

7. 其他方法

7.1. 文件上传

语法

requests.post(url    #必选参数,指定URL地址
              files  #可选参数,指定文件名)

1、发送单个文件

import requests 
url = 'http://xxx.com/'
file_path = './file.txt' 
# 读取文件
with open(file_path, 'rb') as file:
    # 将读取的二进制信息赋值为字典
    files = {'file': file}
    # 通过字典发送post请求
    response = requests.post(url, files=files)
# 获取响应信息
print(response.text)

2、发送多个文件(方法同上,多个文件使用遍历方式)

import requests
 
url = 'http://xxx.com/'
file_paths = {
    'file1': './file1.txt',
    'file2': './file2.txt'
}
 
uploaded_files = {}
 
# 通过循环方式读取多个文件
for field_name, file_path in file_paths.items():
    with open(file_path, 'rb') as file:
        files = {field_name: file}
        response = requests.post(url, files=files)
        uploaded_files[field_name] = response.text
 
print(uploaded_files)

7.2. 代理设置

  • 在计算机网络中,代理(Proxy)是一种充当中间人的服务器,它在客户端和目标服务器之间起到转发和代理的作用。当客户端发送请求时,代理服务器接收请求并将其转发给目标服务器。然后,代理服务器接收来自目标服务器的响应,并将其转发回客户端。

  • 在使用 requests 库发送 HTTP 请求时,代理(Proxy)可以用于访问被限制或无法直接访问的网站、隐藏真实的 IP 地址、实现访问控制等功能。通过配置代理,请求将通过代理服务器,而不是直接与目标服务器通信。这样,目标服务器会认为请求来自代理服务器,而不是真实的客户端。

1、通过proxies参数设置全局代理

import requests
 
# 设置服务器地址和端口
proxies = {
    'http': 'http://xxx.com:8080',
    'https': 'https://xxx.com:8080'
}
 
# 通过proxies发送
response = requests.get(url, proxies=proxies)

2、使用环境变量设置代理

import requests
import os
 
# 通过os获取本地变量去设置代理
os.environ['HTTP_PROXY'] = 'http://xxx.com:8080'
os.environ['HTTPS_PROXY'] = 'https://xxx.com:8080'
 
# 发送请求时,自动在环境变量中读取代理设置
response = requests.get(url)

3、环境变量中读取代理设置

import requests
 
# 定义代理的地址和端口
proxy = 'http://xxx.com:8080'
 
# 创建一个会话
session = requests.Session()
 
# 设置代理
session.proxies = {'http': proxy, 'https': proxy}
 
# 发送请求
response = session.get(url)

4、代理中设置用户、密码

import requests
 
proxies = {
    # 设置用户 : 密码 @ 地址 : 端口
    'http': 'http://username:password@xxx.com:8080',
    'https': 'https://username:password@xxx.com:8080'
}
 
# 通过设置的代理,发送请求
response = requests.get(url, proxies=proxies)

7.3. 快速读取多个地址信息

示例(简单读取某地址信息)

import requests
 
def get_html(url):
    response = requests.get(url)
    if response.status_code == 200:
        return response.text
    else:
        return None
 
def main():
    urls = [
        'https://www.xxx1.com/',
        'https://www.xxx2.com/',
        'https://www.xxx3.com/'
    ]
    for url in urls:
        html = get_html(url)
        print(html)
 
if __name__ == '__main__':
    main()

8. 总结

常用函数与方法总结表

方法/函数 作用 常用参数 参数说明 返回值
requests.get(url, **kwargs) 发送 GET 请求 paramsheaderscookiestimeout params:字典或元组,作为查询参数附加到 URL headers:请求头 timeout:超时时间(秒) Response 对象
requests.post(url, **kwargs) 发送 POST 请求 datajsonheaderscookiestimeout data:表单数据(字典或字节流) json:JSON 数据(自动转 JSON 格式) Response 对象
requests.put(url, **kwargs) 发送 PUT 请求 post 用于更新资源 Response 对象
requests.delete(url, **kwargs) 发送 DELETE 请求 headerstimeout 删除资源 Response 对象
requests.head(url, **kwargs) 发送 HEAD 请求 与 GET 类似,但只返回头部信息 不返回 body Response 对象
requests.options(url, **kwargs) 发送 OPTIONS 请求 无特殊参数 获取服务器支持的 HTTP 方法 Response 对象
requests.request(method, url, **kwargs) 通用请求方法 method(字符串,如 "GET", "POST") 其它参数同上 更灵活的通用方法 Response 对象

Response 对象常用属性与方法

属性/方法 作用 示例
.status_code HTTP 状态码 resp.status_code # 200
.text 响应内容(字符串) resp.text
.content 响应内容(二进制) resp.content
.json() 解析 JSON 响应 resp.json()
.headers 响应头(字典) resp.headers['Content-Type']
.cookies 响应 Cookies resp.cookies
.url 实际请求的 URL(包含跳转后的地址) resp.url
.history 重定向历史 resp.history
.raise_for_status() 检查请求是否成功,失败抛异常 resp.raise_for_status()

常用参数说明表

参数 类型 说明 示例
params dict / list URL 查询参数 params={"q":"python"}
data dict / bytes 表单数据(application/x-www-form-urlencoded data={"username":"test"}
json dict JSON 格式数据(自动转 JSON) json={"name":"Tom"}
headers dict 自定义请求头 headers={"User-Agent":"myapp"}
cookies dict / CookieJar 发送 Cookies cookies={"sessionid":"12345"}
auth tuple HTTP 基本认证 auth=("user","pass")
timeout float / tuple 超时时间(秒),(连接超时, 读取超时) timeout=(3,5)
proxies dict 设置代理 {"http":"http://127.0.0.1:8080"}
verify bool / str SSL 证书验证,False 可忽略,str 指定证书路径 verify=False
allow_redirects bool 是否允许重定向(默认 True) allow_redirects=False
stream bool 是否以流式传输响应 stream=True
files dict 上传文件 files={"file": open("a.txt","rb")}
posted @ 2025-06-15 18:33  kyle_7Qc  阅读(712)  评论(0)    收藏  举报