Python 实现 web 请求与响应
Web请求与响应是 Web 通信的基础。Web 请求由客户端发起,服务器处理后返回响应HTTP(Hypertext Transfer Protocol)是Web 上传输数据的协议,负责浏览器与服务器之间的通信。GET:请求服务器获取资源,通常用于读取数据POST:提交数据到服务器,通常用于表单提交、文件上传等PUT:更新服务器上的资源DELETE:删除服务器上的资源。
什么是 Web 请求与响应?
Web请求与响应是 Web 通信的基础。Web 请求由客户端发起,服务器处理后返回响应
Web 请求
Web 请求通常包括以下几个部分:
- 请求行:包括请求方法 (如 GET、POST、PUT、DELETE)、URL和 HTTP 协议版本(如 HTTP/1.1)
- 请求头:包含关于客户端信息、请求体类型、浏览器类型等的元数据
- 请求体:在 POST请求中包含用户提交的数据,如表单数据或文件
Web 响应
Web 响应由服务器返回,通常包括以下几个部分:
- 响应行:包括 HTTP 协议版本、状态码和状态消息
- 响应头:包括关于响应的信息,如内容类型、服务器信息
- 响应体:包含实际返回的数据(如 HTML页面、JSON数据等)
HTTP 协议概述
HTTP(Hypertext Transfer Protocol)是Web 上传输数据的协议,负责浏览器与服务器之间的通信。常见的 HTTP 方法有:
- GET:请求服务器获取资源,通常用于读取数据
- POST:提交数据到服务器,通常用于表单提交、文件上传等
- PUT:更新服务器上的资源
- DELETE:删除服务器上的资源
常见的 HTTP 状态码包括:
- 200 OK:请求成功,服务器返回所请求的数据
- 301 Moved Permanently:资源已永久移动
- 404 Not Found:请求的资源不存在
- 500 Internal Server Error:服务器内部错误
Python 的 requests 库
Python的 requests 库是发送 HTTP 请求和处理响应的最常用工具,它提供了简单、直观的 API,使得 Web 请求和响应的操作变得非常容易。通过requests,我们可以轻松地发送 GET、POST请求处理 JSON 响应,管理请求头等
安装requests 库
在使用 requests 之前,我们需要先安装它。如果你没有安装,可以通过以下命令安装:
[root@bogon ~]# pip3 install requests
Collecting requests
Downloading requests-2.32.4-py3-none-any.whl.metadata (4.9 kB)
Collecting charset_normalizer<4,>=2 (from requests)
Downloading charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (35 kB)
Collecting idna<4,>=2.5 (from requests)
Downloading idna-3.10-py3-none-any.whl.metadata (10 kB)
Collecting urllib3<3,>=1.21.1 (from requests)
Downloading urllib3-2.4.0-py3-none-any.whl.metadata (6.5 kB)
Collecting certifi>=2017.4.17 (from requests)
Downloading certifi-2025.4.26-py3-none-any.whl.metadata (2.5 kB)
Downloading requests-2.32.4-py3-none-any.whl (64 kB)
━━━━━━━━━━━ 64.8/64.8 1.0 MB/s eta 0:00:00
kB
Downloading certifi-2025.4.26-py3-none-any.whl (159 kB)
━━━━━━━━━━ 159.6/159… 121.9 kB/s eta 0:00:00
kB
Downloading charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (147 kB)
━━━━━━━━━━ 147.3/147.3 54.2 kB/s eta 0:00:00
kB
Downloading idna-3.10-py3-none-any.whl (70 kB)
━━━━━━━━━━ 70.4/70.4 15.5 kB/s eta 0:00:00
kB
Downloading urllib3-2.4.0-py3-none-any.whl (128 kB)
━━━━━━━━━━ 128.7/128.7 21.8 kB/s eta 0:00:00
kB
Installing collected packages: urllib3, idna, charset_normalizer, certifi, requests
Successfully installed certifi-2025.4.26 charset_normalizer-3.4.2 idna-3.10 requests-2.32.4 urllib3-2.4.0
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
发送 GET 请求
GET 请求通常用于获取数据。我们通过requests.get()来发送 GET请求,并可以处理返回的响应
[root@bogon ~]# python3
Python 3.11.6 (main, Dec 18 2024, 22:06:12) [GCC 12.3.1 (openEuler 12.3.1-62.oe2403sp1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
发送 GET请求
>>> response=requests.get('https://www.example.com')
输出响应的状态码
>>> print(response.status_code)
200
输出响应的内容
>>> print(response.text)
<!doctype html>
<html>
<head>
<title>Example Domain</title>
<meta charset="utf-8" />
输出响应头
>>> print(response.headers)
{'Accept-Ranges': 'bytes', 'Content-Type': 'text/html', 'ETag': '"84238dfc8092e5d9c0dac8ef93371a07:1736799080.121134"', 'Last-Modified': 'Mon, 13 Jan 2025 20:11:20 GMT', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'Cache-Control': 'max-age=900', 'Date': 'Thu, 12 Jun 2025 06:33:26 GMT', 'Alt-Svc': 'h3=":443"; ma=93600,h3-29=":443"; ma=93600,quic=":443"; ma=93600; v="43"', 'Content-Length': '648', 'Connection': 'keep-alive'}
获取响应内容的长度
>>> print(len(response.text))
1256
代码解释:
- requests.get()用于发送 GET 请求,获取指定 URL的数据
- response.status code 获取 HTTP 响应状态码
- response.text 获取响应的正文内容(通常是 HTML或 JSON数据)
- response.headers 获取响应头
- len(response.text)返回响应正文的长度,帮助我们了解返回内容的大小
发送 POST 请求
POST 请求用于将数据提交到服务器,通常用于表单提交或上传文件。我们使用requests.post0
来发送 POST 请求
>>> url='https://httpbin.org/post'
>>> data={'name':'lwy','age':25}
>>> response=requests.post(url,data=data)
输出响应状态码
>>> print('Response Body:',response.json())
Response Body: {'args': {}, 'data': '', 'files': {}, 'form': {'age': '25', 'name': 'lwy'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '15', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.32.4', 'X-Amzn-Trace-Id': 'Root=1-684a9e13-1d9f99eb3c4c6787320e3226'}, 'json': None, 'origin': '125.46.147.96', 'url': 'https://httpbin.org/post'}
代码解释:
- requests.post0)用于发送 POST请求,将数据提交到服务器
- data参数是一个字典,包含了我们要提交的数据。requests 会自动将其编码为
- application/x-www-fomm-urlencoded 格式
- response.json()用于解析返回的 JSON 数据
处理响应头和状态码
响应头提供了关于服务器的信息,状态码则告诉我们请求是否成功。我们可以通过response.headers 获取响应头,通过response.status_code 获取状态码
发送 GET请求
>>> response=requests.get('https://www.example.com')
获取响应头
>>> print(response.headers)
{'Accept-Ranges': 'bytes', 'Content-Type': 'text/html', 'ETag': '"84238dfc8092e5d9c0dac8ef93371a07:1736799080.121134"', 'Last-Modified': 'Mon, 13 Jan 2025 20:11:20 GMT', 'Vary': 'Accept-Encoding', 'Content-Encoding': 'gzip', 'Content-Length': '648', 'Cache-Control': 'max-age=1468', 'Date': 'Thu, 12 Jun 2025 09:34:32 GMT', 'Alt-Svc': 'h3=":443"; ma=93600,h3-29=":443"; ma=93600,quic=":443"; ma=93600; v="43"', 'Connection': 'keep-alive'}
获取响应状态码
>>> print(response.status_code)
200
获取内容类型
>>> print(response.headers.get('content-type'))
text/html
代码解释:
- response.headers 返回响应头,包含如 Content-Type、Date、Server 等信息
- response.status code 返回 HTTP 状态码
- response.headers.get(Content-Type’)获取响应的内容类型(如 text/html、 application/json)
发送带查询参数的 GET 请求
在 GET 请求中,我们可以URL传递查询参数。例如,访问一个包含参数的 URL
发送带查询参数的 GET请求
>>> url='https://httpbin.org/get'
>>> garams={'name':'lwy','age':25}
>>> response=requests.get(url,params=params)
输出响应内容
>>> print('Response Body:',response.json())
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/requests/models.py", line 976, in json
return complexjson.loads(self.text, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.11/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.11/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib64/python3.11/json/decoder.py", line 355, in raw_decode
raise 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 "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.11/site-packages/requests/models.py", line 980, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
代码解释:
- params是一个字典,包含要传递的查询参数。requests.get()会自动将这些参数编码到 URL 中
发送带表单数据的 POST 请求
POST 请求可以用来提交表单数据,下面的例子展示了如何使用requests 发送带表单数据的
POST 请求
发送带表单数据的 POST 请求
>>> url='https://httpbin.org/post'
>>> data={'username':'lwy','password':'mypassword'}
>>> response=requests.post(url,data=data)
输出响应的内容
>>> print('Response Body:',response.json())
Response Body: {'args': {}, 'data': '', 'files': {}, 'form': {'password': 'mypassword', 'username': 'lwy'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '32', 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.32.4', 'X-Amzn-Trace-Id': 'Root=1-684aa1be-35cac57c0063862333b0e1f9'}, 'json': None, 'origin': '125.46.147.96', 'url': 'https://httpbin.org/post'}
代码解释:
data参数是一个字典,包含表单提交的数据,requests 会自动将数据编码为
application/x-www-fomm-urlencoded格式
处理 JSON 响应
许多 Web AP|返回的数据格式是JSON,Python 的 requests 库提供了方便的JSON 处理方法
发送 GET请求并获取 JSON 响应
>>> url='https://api.github.com/users/octocat'
>>> response=requests.get(url)
解析 JSON 数据
>>> data=response.json()
输出用户的 GitHub信息
>>> print('User Login:',data['login'])
User Login: octocat
>>> print('User Name:',data['name'])
User Name: The Octocat
代码解释:
response.json()将响应的内容解析为 Python 字典,方便我们处理 JSON 数据
文件操作
文件操作是 Python编程中常见的任务。Python提供了多种方法来读取、写入和管理文件,能够处理文本文件、二进制文件以及目录操作等。掌握文件操作的基础和技巧是高效编程的关键
打开文件的模式
Python使用内置的 open()函数来打开文件。打开文件时,我们需要指定文件模式(即操作文件的方式)。常见的文件模式如下:
常见的文件打开模式
- r:只读模式(默认模式)。文件必须存在。如果文件不存在,会抛出FileNotFoundError 异常
- w:写入模式。如果文件存在,会覆盖文件内容。如果文件不存在,会创建新文件
- a:追加模式。如果文件存在,写入的数据会追加到文件末尾;如果文件不存在,会创建新文件
- x:独占创建模式。若文件已存在,操作会失败并抛出 FileExistsError异常。此模式通常用于创建文件时防止覆盖现有文件
- rb:二进制读取模式,用于读取非文本文件(如图片、音频文件)
- wb:二进制写入模式,用于写入非文本文件
- r+:读写模式。文件必须存在。既可以读取文件内容,也可以写入数据
- w+读写模式。如果文件存在,会覆盖文件内容;如果文件不存在,会创建新文件
- a+:读写模式。文件存在时,数据会追加到文件末尾;如果文件不存在,会创建新文件
- rb+:二进制读写模式
打开文件并使用模式
以只读模式打开文件
>>> with open('example.txt','r') as file:
... content = file.read()
>>> print(content)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'content' is not defined
以写入模式打开文件,文件内容会被覆盖
>>> with open('example.txt','w')as file:
... file.write("lwy\n")
#以追加模式打开文件,新的内容会追加到文件末尾
>>> with open('example.txt','a')as file:
... file.write("lwy\n")
#以二进制模式打开文件(例如读取图片)
>>> with open('image.jpg','rb')as file:
... binary_data=file.read()
读取文件
Python中的文件读取功能非常强大。以下是几种常见的读取方式:
read()方法
read()方法用于读取文件中的所有内容。读取后的内容会作为字符串返回
>>> with open('example.txt','r') as file:
... content=file.read()
readline()方法
read1ine()方法每次读取一行文件内容,适用于需要逐行处理文件的情况
>>> with open('example.txt','r')as file:
...line = file.readline()
...while line:
readlines()方法
readlines()方法会一次性读取文件中的所有行,并将每行数据存储为一个列表的元素,适用于需要读取整个文件并进行行处理的情况
>>>with open('example.txt','r')as file:
...lines= file.readlines()
...for line in lines:
...print(line.strip())
写入文件
Python提供了几种方法将数据写入文件。写入操作常用于日志记录、数据导出等场景
使用 write()方法写入文件
write()方法将指定的字符串写入文件。若文件以w模式打开,原文件内容会被覆盖;若以a模式打开内容会被追加到文件末尾
>>>with open('output.txt','w')as file:
...file.write(“lwy\n”)
使用 writelines()方法写入多行数据
writelines()方法接受一个可选代对象(如列表、元组等),将其元素写入文件中,每个元素将作为-行写入文件
下载文件示例
我们可以通过 requests 库来下载文件,并将其保存到本地。例如,下载一个图片文件:
>>> url='https://www.example.com/image.jpg'
>>> response=requests.get(url)
文件操作中的注意事项
在进行文件操作时,需要注意以下几个问题:
文件是否存在:在打开文件时,必须确保文件路径正确。如果文件不存在,可以使用 os.path.exists()检查文件是否存在,或者使用try-except捕获FileNotFoundError异常
文件权限:在操作文件时,可能会遇到权限不足的问题。例如,尝试写入只读文件,或访问没有读取权限的文件。在这种情况下,可以使用try-except来捕获 PermissionError 异常
文件自动关闭:使用with open()语句时,Python会自动管理文件的打开和关闭,无需显式调用file.close()。这有助于避免文件未关闭的问题,减少资源泄漏的风险
其他常用文件操作
获取文件信息
Python提供了os和os.path 模块,可以获取文件的大小、修改时间等信息
删除文件
使用os.remove()可以删除文件:
错误处理与异常捕获
在进行 Web 请求时,可能会发生各种错误,例如网络超时、服务器错误等。requests 库通过异常处理机制帮助我们捕获这些错误。Pvthon 的 try语句能够捕获和处理代码块中的异常,从而避免程序崩溃,并且提供了处理错误的机会。
try 语句的使用
try语句用于捕获和处理异常,它由三部分组成:
- try块:包含可能会引发异常的代码。当代码运行过程中发生错误时,程序会跳到相应的 except块进行处理
- except块:当 try块中的代码出现异常时,程序会跳转到 except块执行。在 except 中可以指定要捕获的异常类型,如Timeout、HTTPError 等
- else 块(可选):如果try块中的代码没有抛出异常,则会执行 else块中的代码
- finally块(可选) :无论是否发生异常,finally 块中的代码都会执行,通常用于清理资源(如关闭文件、数据库连接等)
捕获常见异常
代码解释:
1.try块:首先发起 HTTP请求,设置超时时间为5秒,并使用response.raise for status()来检查响应的状态码。如果服务器返回了错误的状态码(如 404、500),raise for status0)会抛出
HTTPError 异常。
2.except块:
- Timeout: 如果请求超时(超过设置的5秒),程序会捕获到Timeout 异常,并打印“Request
timed out" - HTTPError:如果响应的状态码表明出现 HTTP 错误(例如 404表示未找到页面),程序会捕获到 HTTPError 异常,并打印相关错误信息
- RequestException:捕获其他类型的网络相关错误(如连接问题、DNS 解析失败等)RequestException 是所有 requests 库异常的基类,可以捕获任何requests 库抛出的异常
3 finally 块:finally 中的代码无论是否发生异常都会被执行。通常用于释放资源或做一些收尾工作。这里我们仅打印“Request attempt completed”表示请求的结束
异常处理总结:
- 异常处理让我们在程序运行中捕获到错误并做出相应处理,避免程序崩溃
- 通过 try…except结构,可以精确捕获并处理不同类型的异常
- finally 块用于清理工作,在请求处理完成后可以释放资源(如关闭文件、数据库连接等)
更多推荐
所有评论(0)