Python 网络请求利器:requests 包详解与实战

诸神缄默不语-个人技术博文与视频目录

文章目录

  • 一、前言
  • 二、安装方式
  • 三、基本使用
    • 1. 发起 GET 请求
    • 2. 发起 POST 请求
  • 四、requests请求调用常用参数
    • 1. URL
    • 2. 数据data
    • 3. 请求头 headers
    • 4. 参数 params
    • 5. 超时时间 timeout
    • 6. 文件上传 file:上传纯文本文件流
    • 7. json
  • 五. 响应的属性和函数
    • 1. 属性:headers、cookies、编码格式
    • 2. 异常处理:raise_for_status()
  • 六、Session 会话对象(保持登录态)
  • 七、进阶用法
    • 1. 上传压缩文件
    • 2. 并发
  • 七、常见异常
    • 1. requests.exceptions.JSONDecodeError
    • 2. requests.exceptions.Timeout
    • 3. requests.exceptions.ProxyError: HTTPSConnectionPool
  • 八、实战案例:爬取豆瓣电影 Top250(示例)
  • 本文撰写过程中参考的其他网络资料

一、前言

在进行网络编程或爬虫开发时,我们经常需要向网页或服务器发送 HTTP 请求,获取数据。这时,requests 包无疑是最受欢迎、最简洁易用的 Python 库之一。

相比原生的 urllib 模块,requests 提供了更人性化的 API,更容易上手,几乎成为了网络请求的“标准库”。

本文将介绍 requests 的基本用法、进阶操作以及常见问题处理,配合实际代码演示,带你快速掌握这个神器!

https://httpbin.org/是一个简单的用来模拟各种HTTP服务请求的网站,以下很多代码示例都会用这个网站的链接来实现。
因为这个网站部署在海外,所以可能会出现网络访问的问题,可以通过部署到本地来解决。部署到本地可以参考官方教程,或者这篇博文:五、接口测试 — Httpbin介绍(请求调试工具) - 知乎

二、安装方式

pip install requests

三、基本使用

关于get请求和post请求的区别请参考我撰写的另一篇博文:Web应用中的GET与POST请求详解

1. 发起 GET 请求

import requestsresponse = requests.get('https://httpbin.org/get')
print(response.status_code)      # 状态码
print(response.text)             # 响应内容(字符串)
print(response.json())           # 如果是 JSON,解析成字典

2. 发起 POST 请求

payload = {'username': 'test', 'password': '123456'}
response = requests.post('https://httpbin.org/post', data=payload)
print(response.json())

四、requests请求调用常用参数

1. URL

就是第一个参数,网站的链接地址

2. 数据data

请求携带的数据。
如果值是字符串或字节流,默认不设置Content-Type会设置。
如果值是字典、元组组成的列表或列表对象,会默认Content-Type会设置为application/x-www-form-urlencoded,也就是HTML表单形式的键值对数据。(对Content-Type的详细介绍请见下一节headers参数)

import requests
import jsonpayload = {"key1": "value1", "key2": "value2"}# String payload in json format
r = requests.post("https://httpbin.org/post", data="a random sentence")
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# String payload in json format
r = requests.post("https://httpbin.org/post", data=json.dumps(payload))
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# String payload in json content type
r = requests.post("https://httpbin.org/post",data=json.dumps(payload),headers={"Content-Type": "application/json"},
)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# Dictionary payload
r = requests.post("https://httpbin.org/post", data=payload)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# List of tuples payload
payload_tuples = [("key1", "value1"), ("key2", "value2")]
r = requests.post("https://httpbin.org/post", data=payload_tuples)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# Bytes payload
payload_bytes = "key1=value1&key2=value2".encode("utf-8")
r = requests.post("https://httpbin.org/post", data=payload_bytes)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))

3. 请求头 headers

一般会携带请求的Content-Type、系统信息(如使用的设备、编码方式等)、认证信息、时间戳等

headers = {'User-Agent': 'MyUserAgent/1.0'}
response = requests.get('https://httpbin.org/headers', headers=headers)
print(response.json())

Content-Type的常见类型:
在这里插入图片描述
(图源1

4. 参数 params

这个在get请求中的效果就类似于直接在URL后面加?k=v

params = {'q': 'python'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url)  # 实际请求的完整 URL

输出:https://httpbin.org/get?q=python

5. 超时时间 timeout

response = requests.get('https://httpbin.org/delay/3', timeout=2)

如果超过2秒没响应,会抛出 requests.exceptions.Timeout 异常。

6. 文件上传 file:上传纯文本文件流

files = {'file': open('test.txt', 'rb')}
response = requests.post('https://httpbin.org/post', files=files)
print(response.text)

↑ 需要注意的是虽然file参数确实可以直接这么传文件流……但我没咋见过真这么干的。
一般纯文本不用file传,一般都直接塞data里面带过去。
非纯文本文件流(二进制字节流),我一般看比较多的传输方式是把字节流转换为base64编码塞到data里带。用base64编码的代码可参考我写的另一篇博文:深入理解 Python 的 base64 模块
(不过说实话直接用file参数传文件流好像实际上背后也经过了base64编码-解码的过程,但是大家都这么干一定有大家的道理)

7. json

用json参数传JSON对象(在Python 3中表现为字典对象)就相当于用data参数传JSON对象、然后显示设置Content-Type为application/json

payload = {'id': 1, 'name': 'chatgpt'}
response = requests.post('https://httpbin.org/post', json=payload)
print(response.json())

上面这个请求和下面这个请求是一样的:

response = requests.post("https://httpbin.org/post",data=json.dumps(payload),headers={"Content-Type": "application/json"},
)
print(response.json())

作为对比可以看看另外两种请求参数格式的效果(可以注意到第一种写法返回的data和json值好歹还是一样的,第二种写法的话对象就放到form里了,因为是以表单对象形式来解析的):

response = requests.post("https://httpbin.org/post",data=json.dumps(payload)
)
print(response.json())response = requests.post("https://httpbin.org/post",data=payload
)
print(response.json())

五. 响应的属性和函数

1. 属性:headers、cookies、编码格式

r = requests.get('https://httpbin.org/get')
print(r.headers)
print(r.cookies)
print(r.encoding)

2. 异常处理:raise_for_status()

如果status_code不是200就报错

六、Session 会话对象(保持登录态)

requests.Session() 可以模拟保持会话,适合需要登录认证的网站。

s = requests.Session()
s.post('https://httpbin.org/cookies/set', data={'cookie': 'value'})
response = s.get('https://httpbin.org/cookies')
print(response.text)

七、进阶用法

1. 上传压缩文件

  1. gzip实现
    import requests
    import gzip
    import jsondata = json.dumps({'key': 'value'}).encode('utf-8')
    compressed_data = gzip.compress(data)headers = {'Content-Encoding': 'gzip'}response = requests.post('https://httpbin.dev/api', data=compressed_data, headers=headers)
    response.raise_for_status()print("Gzip Compressed Request Status:", response.status_code)
    
  2. brotli实现
    import requests
    import brotlidata = json.dumps({'key': 'value'}).encode('utf-8')
    compressed_data = brotli.compress(data)headers = {'Content-Encoding': 'br'}response = requests.post('https://httpbin.dev/api', data=compressed_data, headers=headers)
    response.raise_for_status()print("Brotli Compressed Request Status:", response.status_code)
    

2. 并发

  1. httpx实现(来源于Concurrency vs Parallelism)
    import asyncio
    import httpx
    import time# Asynchronous function to fetch the content of a URL
    async def fetch(url):async with httpx.AsyncClient(timeout=10.0) as client:response = await client.get(url)return response.text# Concurrently fetch multiple URLs using asyncio.gather
    async def concurrent_fetch(urls):tasks = [fetch(url) for url in urls]return await asyncio.gather(*tasks)# Synchronous version to demonstrate performance difference
    def sync_fetch(urls):results = []for url in urls:response = httpx.get(url)results.append(response.text)return resultsdef run_concurrent():urls = ["http://httpbin.org/delay/2"] * 100  # Use the same delay for simplicitystart_time = time.time()# Running fetch requests concurrentlyasyncio.run(concurrent_fetch(urls))duration = time.time() - start_timeprint(f"Concurrent fetch completed in {duration:.2f} seconds")def run_sync():urls = ["http://httpbin.org/delay/2"] * 100  # Use the same delay for simplicitystart_time = time.time()# Running fetch requests synchronouslysync_fetch(urls)duration = time.time() - start_timeprint(f"Synchronous fetch completed in {duration:.2f} seconds")if __name__ == "__main__":print("Running concurrent version:")# Concurrent fetch completed in 2.05 secondsrun_concurrent()print("Running synchronous version:")# Synchronous fetch completed in 200.15 secondsrun_sync()
    
  2. threading实现
    import threading
    import requestsdef post_data(data):requests.post('https://httpbin.dev/api', json=data)# Sample data list
    data_list = [{'name': 'User1'}, {'name': 'User2'}]threads = []
    for data in data_list:thread = threading.Thread(target=post_data, args=(data,))threads.append(thread)thread.start()for thread in threads:thread.join()
    

关于并发的相关知识也可以参考我写的另一篇博文:Python中的并发与并行

七、常见异常

1. requests.exceptions.JSONDecodeError

如果response带的报文不是JSON,还调用response.json()函数,会报requests.exceptions.JSONDecodeError错误,完整的报错信息类似这样:

Traceback (most recent call last):File "myenv_path\Lib\site-packages\requests\models.py", line 974, in jsonreturn complexjson.loads(self.text, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\json\__init__.py", line 346, in 
loadsreturn _default_decoder.decode(s)^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\json\decoder.py", line 337, in decodeobj, end = self.raw_decode(s, idx=_w(s, 0).end())^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\json\decoder.py", line 355, in raw_decoderaise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)During handling of the above exception, another exception occurred:Traceback (most recent call last):File "tryrequests1.py", line 6, in <module>print(response.json())           # 如果是 JSON,解析成字典^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\models.py", line 978, in jsonraise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

2. requests.exceptions.Timeout

等待请求返回结果的时长超过了timeout参数设置的时长。

3. requests.exceptions.ProxyError: HTTPSConnectionPool

访问URL失败。
有时候网络服务不稳定是临时的,直接重试几次就行。重试的策略可以参考我撰写的另一篇博文:Python3:在访问不可靠服务时的重试策略(持续更新ing…)

一个典型的由于临时的网络不稳定而产生的访问失败报错输出全文:

Traceback (most recent call last):File "myenv_path\Lib\site-packages\urllib3\connectionpool.py", line 789, in urlopenresponse = self._make_request(^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\connectionpool.py", line 536, in _make_requestresponse = conn.getresponse()^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\connection.py", line 507, in getresponsehttplib_response = super().getresponse()^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\http\client.py", line 1374, in getresponseresponse.begin()File "myenv_path\Lib\http\client.py", line 318, in beginversion, status, reason = self._read_status()^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\http\client.py", line 287, in _read_statusraise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without responseThe above exception was the direct cause of the following exception:urllib3.exceptions.ProxyError: ('Unable to connect to proxy', RemoteDisconnected('Remote end closed connection without response'))The above exception was the direct cause of the following exception:Traceback (most recent call last):File "myenv_path\Lib\site-packages\requests\adapters.py", line 667, in sendresp = conn.urlopen(^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\connectionpool.py", line 843, in urlopenretries = retries.increment(^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\util\retry.py", line 519, in incrementraise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded with url: /cookies (Caused by ProxyError('Unable to connect to proxy', RemoteDisconnected('Remote end 
closed connection without response')))During handling of the above exception, another exception occurred:Traceback (most recent call last):File "tryrequests1.py", line 5, in <module>response = s.get('https://httpbin.org/cookies')^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\sessions.py", line 602, in getreturn self.request("GET", url, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\sessions.py", line 589, in requestresp = self.send(prep, **send_kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\sessions.py", line 703, in sendr = adapter.send(request, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\adapters.py", line 694, in sendraise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded 
with url: /cookies (Caused by ProxyError('Unable to connect to proxy', RemoteDisconnected('Remote end closed connection without response')))

八、实战案例:爬取豆瓣电影 Top250(示例)

import requests
from bs4 import BeautifulSoupheaders = {'User-Agent': 'Mozilla/5.0'}for start in range(0, 250, 25):url = f'https://movie.douban.com/top250?start={start}'r = requests.get(url, headers=headers)soup = BeautifulSoup(r.text, 'html.parser')titles = soup.find_all('span', class_='title')for title in titles:print(title.text)

本文撰写过程中参考的其他网络资料

  1. What is the difference between the ‘json’ and ‘data’ parameters in Requests? | WebScraping.AI
  2. python requests.post() 请求中 json 和 data 的区别 - 小嘉欣 - 博客园
  3. Python requests.post()方法中data和json参数的使用_requests.post中data和json是否可以同时设置-CSDN博客

在这里插入图片描述


  1. Python requests POST ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux入门四:Linux 编译器

一、C 语言编译器 GCC&#xff1a;开启编程之旅 1.1 GCC 安装&#xff1a;一站式工具链 GCC&#xff08;GNU Compiler Collection&#xff09;是 Linux 下最常用的 C/C 编译器&#xff0c;支持多种编程语言。安装命令&#xff08;适用于 Debian/Ubuntu 系统&#xff09;&…

建筑兔零基础自学记录69|爬虫Requests-2

Requests库初步尝试 #导入requests库 import requests #requests.get读取百度网页 rrequests.get(http://www.baidu.com) #输出读取网页状态 print(r.status_code) #输出网页源代码 print(r.text) HTTP 状态码是三位数字&#xff0c;用于表示 HTTP 请求的结果。常见的状态码有…

Web测试流程及注意点

在Web工程过程中&#xff0c;基于Web系统的测试、确认和验收是一项重要而富有挑战性的工作。基于Web的系统测试与传统的软件测试不同&#xff0c;它不但需要检查和验证是否按照设计的要求运行&#xff0c;而且还要测试系统在不同用户的浏览器端的显示是否合适。 重要的是&…

基于MATLAB/simulink的信号调制仿真--AM调制

实验内容&#xff1a; 假设y(t)(20.5*2cos&#xff08;2*pi*1000*t&#xff09;)*5cos&#xff08;2*pi*2*1e4*t&#xff09;调幅系统&#xff0c;请将一个频率为1000HZ的余弦波信号&#xff0c;通过进行AM调制&#xff0c;载波信号频率为20kHZ的余弦波&#xff0c;调制度ma0.…

通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”

一、PSI5是什么&#xff1f; 一句话秒懂 PSI5就像传感器界的“防弹信使”&#xff1a;在汽车安全系统&#xff08;如气囊&#xff09;中&#xff0c;用两根线同时完成供电数据传输&#xff0c;即便车祸时线路受损&#xff0c;仍能确保关键信号准确送达&#xff01; 基础概念…

数据结构与算法-图论-复习1(单源最短路,全源最短路,最小生成树)

1. 单源最短路 单一边权 BFS 原理&#xff1a;由于边权为单一值&#xff0c;可使用广度优先搜索&#xff08;BFS&#xff09;来求解最短路。BFS 会逐层扩展节点&#xff0c;由于边权相同&#xff0c;第一次到达某个节点时的路径长度就是最短路径长度。 用法&#xff1a;适用…

【WRF理论第十七期】单向/双向嵌套机制(含namelist.input详细介绍)

WRF运行的单向/双向嵌套机制 准备工作&#xff1a;WRF运行的基本流程namelist.input的详细设置&time_control 设置&domain 嵌套结构&bdy_control 配置部分 namelist 其他注意事项Registry.EM 运行 ARW 嵌套双向嵌套&#xff08;two-way nesting&#xff09;单向嵌套…

怎么查看苹果手机和ipad的设备信息和ios udid

你知道吗&#xff1f;我们每天使用的iPhone和iPad&#xff0c;其实隐藏着大量详细的硬件与系统信息。除了常见的系统版本和序列号外&#xff0c;甚至连电池序列号、摄像头序列号、销售地区、芯片型号等信息&#xff0c;也都可以轻松查到&#xff01; 如果你是开发者、维修工程…

matlab内置的git软件版本管理功能

1、matlab多人协作开发比普通的嵌入式软件开发困难很多 用过matlab的人都知道&#xff0c;版本管理对于matlab来说真的很费劲&#xff0c;今天介绍的这个工具也不是说它就解决了这个痛点&#xff0c;只是让它变得简单一点。版本管理肯定是不可或缺的&#xff0c;干就完了 2、…

vscode集成deepseek实现辅助编程(银河麒麟系统)【详细自用版】

针对开发者用户&#xff0c;可在Visual Studio Code中接入DeepSeek&#xff0c;实现辅助编程。 可参考我往期文章在银河麒麟系统环境下部署DeepSeek&#xff1a;基于银河麒麟桌面&&服务器操作系统的 DeepSeek本地化部署方法【详细自用版】 一、前期准备 &#xff08…

Java 大厂面试题 -- JVM 深度剖析:解锁大厂 Offe 的核心密钥

最近佳作推荐&#xff1a; Java大厂面试高频考点&#xff5c;分布式系统JVM优化实战全解析&#xff08;附真题&#xff09;&#xff08;New&#xff09; Java大厂面试题 – JVM 优化进阶之路&#xff1a;从原理到实战的深度剖析&#xff08;2&#xff09;&#xff08;New&#…

数据库实践题目:在线书店管理系统

完整的数据库实践题目&#xff1a;在线书店管理系统 数据库表结构及示例数据 书籍表(books) CREATE TABLE books ( book_id INT PRIMARY KEY, title VARCHAR(100) NOT NULL, author VARCHAR(50) NOT NULL, publisher VARCHAR(50), publish_year INT, category VARCHAR(30), …

Linux 入门指令(1)

&#xff08;1&#xff09;ls指令 ls -l可以缩写成 ll 同时一个ls可以加多个后缀 比如 ll -at (2)pwd指令 &#xff08;3&#xff09;cd指令 cd .是当前目录 &#xff08;4&#xff09;touch指令 &#xff08;5&#xff09;mkdir指令 &#xff08;6&#xff09;rmdir和rm…

图灵逆向——题七-千山鸟飞绝

目录列表 过程分析headers头部M参数分析载荷x参数分析响应数据解密分析 代码实现 一进来还是一个无限debugger&#xff0c;前面有讲怎么过&#xff0c;这里直接过掉~ 老规矩&#xff0c;养成习惯&#xff0c;先看请求头里有没有加密参数发现好像是有个M&#xff0c;它是个32位…

上门预约洗鞋店小程序都具备哪些功能?

现在大家对洗鞋子的清洗条件越来越高&#xff0c;在家里不想去&#xff0c;那就要拿去洗鞋店去洗。如果有的客户没时间去洗鞋店&#xff0c;这个时候&#xff0c;有个洗鞋店小程序就可以进行上门取件&#xff0c;帮助没时间的客户去取需要清洗的鞋子&#xff0c;这样岂不是既帮…

Node.js EventEmitter 深入解析

Node.js EventEmitter 深入解析 概述 Node.js 作为一种强大的 JavaScript 运行环境&#xff0c;以其异步、事件驱动特性在服务器端编程中占据了重要地位。EventEmitter 是 Node.js 中处理事件的一种机制&#xff0c;它允许对象&#xff08;称为“发射器”&#xff09;发出事件…

C++11QT复习 (十九)

文章目录 Day13 C 时间库和线程库学习笔记&#xff08;Chrono 与 Thread&#xff09;一、时间库 <chrono>1.1 基本概念1.2 使用示例1.3 duration 字面量单位 二、线程库 <thread>2.1 基本用法2.2 数据竞争&#xff08;Race Condition&#xff09;2.3 加锁&#xff…

C++初阶-C++的讲解1

目录 1.缺省(sheng)参数 2.函数重载 3.引用 3.1引用的概念和定义 3.2引用的特性 3.3引用的使用 3.4const引用 3.5.指针和引用的关系 4.nullptr 5.总结 1.缺省(sheng)参数 &#xff08;1&#xff09;缺省参数是声明或定义是为函数的参数指定一个缺省值。在调用该函数是…

Redisson 实现分布式锁

在平常的开发工作中&#xff0c;我们经常会用到锁&#xff0c;那么锁有什么用呢&#xff1f;锁主要是控制对共享资源的访问顺序&#xff0c;防止多个线程并发操作导致数据不一致的问题。经常可能会听到乐观锁、悲观锁、分布式锁、行锁、表锁等等&#xff0c;那么我们今天总结下…

环境—Ubuntu24(py3.12)安装streamlit(虚拟环境py3.9)

请尽可能不用Ubuntu24请直接跳7.查看解决方案 Action Log 在Ubuntu 24.04中更换为清华源的步骤【Bug】Python 3.12 on Ubuntu 24.04 is Externally Managed - PIP is broken 相关解决方案 从 Ubuntu 24.04 开始&#xff0c;有两个选项&#xff1a; 1. install python pacakg…