Python爬虫(一)- Requests 安装与基本使用教程
文章目录
- 前言
- 一、简介及安装
- 1. 简介
- 2. 安装 Requests
- 2.1 安装
- 2.2 检查安装是否成功
- 二、使用 Requests 发送 HTTP 请求
- 1. 发送 GET 请求
- 2. 发送 POST 请求
- 3. 发送 PUT 请求
- 4. 发送 DELETE 请求
- 5. 发送 HEAD 请求
- 6. 发送 OPTIONS 请求
- 三、传递参数
- 1. GET 请求传递 URL 参数
- 1.1 使用字典传递单个值
- 1.2 使用字典传递多个相同键的值
- 1.3 忽略值为 None 的键
- 2. POST 请求传递参数
- 2.1 表单编码的数据(application/x-www-form-urlencoded)
- 2.2 JSON 编码的数据(application/json)
- 2.2.1 手动编码
- 2.2.2 使用 json 参数
- 2.3 上传文件(multipart/form-data)
- 2.3.1 使用 files 参数上传文件
- 四、响应内容
- 1. 文本响应内容
- 2. 二进制响应内容
- 3. JSON 响应内容
- 4. 原始响应内容
- 五、定制请求头
- 六、响应
- 1. 响应状态码
- 2. 响应头
- 3. Cookie
- 3.1 获取服务器响应的 Cookie
- 3.2 向服务器发送 Cookie
- 3.2.1 使用 cookies 参数传递一个字典
- 4. 重定向
- 4.1 查看重定向历史记录
- 4.2 禁用重定向
- 4.3 启用 HEAD 请求的重定向
- 5. 超时
- 6. 错误与异常
前言
本篇文章将详细介绍 requests 库的基本用法,包括安装、发送请求、处理响应、传递参数等内容。通过这些内容,读者将能够掌握如何使用 requests 库进行高效的网络请求,从而为后续的项目开发打下坚实的基础。希望本文能帮助您更好地理解和应用 requests 库,提升您的 Python 编程技能。
一、简介及安装
1. 简介
requests
是一个用于发送HTTP请求的Python库,它简化了与Web服务交互的过程,使开发者能够轻松地构建和解析HTTP请求和响应。其简洁易用的API设计使得即使是初学者也能快速上手。
使用版本:
python | requests | |
---|---|---|
版本 | 3.8.5 | 2.31.0 |
2. 安装 Requests
2.1 安装
最简单的方法是通过Python的包管理工具pip
来安装requests
。
执行如下命令安装requests 2.31.0
。
pip install requests==2.31.0 -i https://mirrors.aliyun.com/pypi/simple/
2.2 检查安装是否成功
执行如下命令查看requests
是否安装成功。
pip show requests
安装成功如下图所示。
二、使用 Requests 发送 HTTP 请求
1. 发送 GET 请求
import requests
url = 'http://httpbin.org/get'
response = requests.get(url=url)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
2. 发送 POST 请求
import requests
url = 'http://httpbin.org/post'
payload = {'key': 'value'}
response = requests.post(url=url, data=payload)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
3. 发送 PUT 请求
import requests
url = 'http://httpbin.org/put'
payload = {'key': 'value'}
response = requests.put(url=url, data=payload)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
4. 发送 DELETE 请求
import requests
url = 'http://httpbin.org/delete'
response = requests.delete(url=url)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
5. 发送 HEAD 请求
HEAD
请求是一种 HTTP 方法,它与 GET
请求类似,但服务器在响应中只返回头部信息而不包含消息体。这意味着你可以获取关于资源的信息(如状态码、内容类型、最后修改时间等)而无需下载整个资源。这对于检查链接的有效性或获取元数据非常有用。
import requests
url = 'http://httpbin.org/get'
response = requests.head(url=url)
# 打印服务器响应
print(response.text)
6. 发送 OPTIONS 请求
OPTIONS
请求是一种 HTTP 方法,用于描述目标资源所支持的通信选项。它通常用来检查服务器对于特定URL支持哪些HTTP方法(如 GET, POST, PUT, DELETE 等),以及获取其他关于如何与资源交互的信息。
在跨域资源共享 (CORS) 的场景中,浏览器会在发送非简单请求(例如带有自定义头部信息或使用某些HTTP动词)之前自动发出 OPTIONS
预检请求,以确保服务器允许即将进行的实际请求。这种预检机制是 CORS 安全模型的一部分,用以防止可能的跨站脚本攻击 (XSS)。
import requests
url = 'http://httpbin.org/get'
response = requests.options(url=url)
# 打印服务器响应
print(response.text)
三、传递参数
1. GET 请求传递 URL 参数
当你想要为URL的查询字符串(query string)添加数据时,你可以使用 params
关键字参数来提供这些参数。params
接受一个字典或包含键值对的列表,这些键值对会被编码到URL中,跟在问号(?)后面。
1.1 使用字典传递单个值
如果你想传递单个键值对,可以使用一个Python字典作为 params
的值。例如,要传递 key1=value1
和 key2=value2
到 www.baidu.com/get
,可以这样做:
import requests
# 定义URL地址
url = 'https://www.baidu.com/get'
# 定义要传递的参数
payload = {'key1': 'value1', 'key2': 'value2'}
# 发送GET请求并附带参数
response = requests.get(url=url, params=payload)
# 打印出构建的URL
print(response.url)
打印出构建的URL为:
https://www.baidu.com/get?key1=value1&key2=value2
1.2 使用字典传递多个相同键的值
有时可能需要为同一个键传递多个值。在这种情况下,可以将值作为列表传递:
import requests
# 定义URL地址
url = 'https://www.baidu.com/get'
# 定义要传递的参数
payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
# 发送GET请求并附带参数
response = requests.get(url=url, params=payload)
# 打印出构建的URL
print(response.url)
打印出构建的URL为:
https://www.baidu.com/get?key1=value1&key2=value2&key2=value3
1.3 忽略值为 None 的键
如果在字典中包含值为 None
的键,这些键不会被添加到URL的查询字符串中。例如:
import requests
# 定义URL地址
url = 'https://www.baidu.com/get'
# 定义要传递的参数
payload = {'key1': 'value1', 'key2': None}
# 发送GET请求并附带参数
response = requests.get(url=url, params=payload)
# 打印出构建的URL
print(response.url)
打印出构建的URL为:
https://www.baidu.com/get?key1=value1
2. POST 请求传递参数
2.1 表单编码的数据(application/x-www-form-urlencoded)
当需要发送类似于 HTML 表单的数据时,可以简单地向 data
参数传递一个字典。这些数据会在发出请求时自动编码为表单形式。
import requests
# 定义要发送的POST请求的URL
url = 'http://httpbin.org/post'
# 定义要传递的参数
payload = {'key1': 'value1', 'key2': 'value2'}
# 发送POST请求并附带参数
response = requests.post(url=url, data=payload)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
如果有多个值对应同一个键,可以传递一个元组列表:
import requests
# 定义要发送的POST请求的URL
url = 'http://httpbin.org/post'
# 多个相同键的值作为元组列表传递
payload = [('key1', 'value1'), ('key1', 'value2')]
# 发送POST请求并附带参数
response = requests.post(url=url, data=payload)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
2.2 JSON 编码的数据(application/json)
对于 API 请求,通常接受 JSON 编码的数据。有两种方式可以做到这一点。
2.2.1 手动编码
使用 json.dumps()
方法将字典转换为 JSON 字符串,并将其传递给 data
参数。
import requests
import json
# 定义要发送的POST请求的URL
url = 'http://httpbin.org/post'
# 定义要传递的参数
payload = {'key1': 'value1'}
# 发送POST请求并附带参数
response = requests.post(url=url, data=json.dumps(payload))
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
2.2.2 使用 json 参数
直接传递字典给 json
参数,它会自动处理编码。
import requests
# 定义要发送的POST请求的URL
url = 'http://httpbin.org/post'
# 定义要传递的参数
payload = {'key1': 'value1'}
# 发送POST请求并附带参数
response = requests.post(url=url, json=payload)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
2.3 上传文件(multipart/form-data)
2.3.1 使用 files 参数上传文件
上传文件只需要定义一个字典,其中键是表单字段名,值是一个文件对象或包含文件内容的字符串。如果需要,还可以指定文件名、MIME 类型和额外的请求头。
import requests
# 定义要发送的POST请求的URL
url = 'http://httpbin.org/post'
# 上传文件示例
files = {'file': open('D:\\demo.xls', 'rb')}
response = requests.post(url=url, files=files)
# 指定文件名、类型和额外头部
# files = {'file': ('demo.xls', open('D:\\demo.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
# response = requests.post(url, files=files)
# 发送字符串作为文件
# files = {'file': ('demo.csv', 'v1,v2,v3,v4\nv5,v6,v7,v8\n')}
# response = requests.post(url, files=files)
# 打印服务器响应
print(response.text)
打印服务器响应的结果为:
四、响应内容
1. 文本响应内容
在与服务器交互后,可以读取其返回的内容。
requests
库会自动处理从服务器接收的数据解码。
自动解码:requests
会基于 HTTP 头部信息对响应编码作出推测,并使用response.text
访问时自动解码。
修改编码:可以通过response.encoding
属性来查看或改变推测的编码方式。
import requests
url = 'https://api.github.com/events'
response = requests.get(url=url)
# 打印文本响应内容
print(response.text)
# 查看推测的文本编码
print(response.encoding)
# 修改编码方式并打印文本响应内容
response.encoding = 'ISO-8859-1'
print(response.text)
打印的结果为:
2. 二进制响应内容
对于非文本类型的响应,比如图片、文件等,应该使用 response.contentt
来访问原始的字节数据。requests
自动处理 gzip
和 deflate
编码的响应。
import requests
url = 'https://img3.doubanio.com/view/photo/m_ratio_poster/public/p480747492.jpg'
response = requests.get(url=url)
# 打印二进制响应内容
print(response.content)
打印的结果为:
3. JSON 响应内容
对于 JSON 数据,requests
提供了内置的 JSON 解码器。
import requests
url = 'https://jsonplaceholder.typicode.com/posts'
response = requests.get(url=url)
print(response.json)
需要注意的是,成功调用 response.json()
并不意味着 HTTP 请求的成功。要检查请求是否成功,应当检查 response.status_code
的返回值是否和期望相同。
4. 原始响应内容
在特殊情况下,可能需要获取来自服务器的原始套接字响应。这需要确保在初始请求中设置了 stream=True
。
import requests
url = 'https://api.github.com/events'
response = requests.get(url=url, stream=True)
# 打印原始响应对象
print(response.raw)
打印的结果为:
<urllib3.response.HTTPResponse object at 0x0000013F42A42D60>
通常,推荐使用 Response.iter_content()
方法来流式处理大文件下载,而不是直接操作 Response.raw
。
import requests
# 定义要请求的 URL
url = 'https://api.github.com/events'
# 发送 GET 请求到指定的 URL,使用 stream=True 以便逐块下载内容
response = requests.get(url=url, stream=True)
# 打开一个文件以写入二进制数据,路径为 'D:\\demo.txt'
with open('D:\\demo.txt', 'wb') as fd:
# 遍历响应内容,按块读取数据,块大小为 8192 字节
for chunk in response.iter_content(chunk_size=8192):
# 将读取的块写入文件
fd.write(chunk)
五、定制请求头
如果想为请求添加 HTTP 头部信息,只需要传递一个字典给 headers
参数就可以。
import requests
url = 'https://api.github.com/some/endpoint'
# 定制请求头
headers = {'user-agent': 'my-app/0.0.1'}
response = requests.get(url, headers=headers)
print(response.text)
打印的结果为:
{"message":"Not Found","documentation_url":"https://docs.github.com/rest","status":"404"}
注意事项:
- 如果在 .netrc 中设置了用户认证信息,使用 headers= 设置的授权就不会生效。而如果设置了 auth= 参数,
.netrc
的设置就无效了。 - 如果被重定向到别的主机,授权 header 就会被删除。
- 代理授权 header 会被 URL 中提供的代理身份覆盖掉。
- 在我们能判断内容长度的情况下,header 的 Content-Length 会被改写。
六、响应
1. 响应状态码
在使用 requests
库发送 HTTP 请求后,可以通过 Response.status_code
属性来检查服务器返回的状态码。这可以帮助我们了解请求是否成功完成或发生了什么类型的错误。
import requests
url = 'http://httpbin.org/get'
response = requests.get(url=url)
# 打印响应状态码
print(response.status_code)
打印的响应状态码为:
200
为了方便引用和比较,requests
提供了一个内置的状态码查询对象 requests.codes
,它包含了所有标准的 HTTP 状态码作为属性。
import requests
url = 'http://httpbin.org/get'
response = requests.get(url=url)
# 打印响应结果
print(response.status_code == requests.codes.ok)
打印的结果为:
True
如果请求导致了客户端(4XX)或服务器端(5XX)错误,我们可以使用 Response.raise_for_status()
方法来抛出异常。
import requests
url = 'http://httpbin.org/status/404'
response = requests.get(url=url)
# 打印响应状态码
print(response.status_code)
print(response.raise_for_status())
打印结果如下图所示:
当请求成功时(如状态码为 200),调用 raise_for_status()
不会做任何事情,表示一切正常。
import requests
url = 'http://httpbin.org/get'
response = requests.get(url=url)
# 打印响应状态码
print(response.status_code)
print(response.raise_for_status())
打印的结果为:
200
None
2. 响应头
通过 Response.headers
属性可以查看以 Python 字典形式展示的服务器响应头信息。这个字典是专门为 HTTP 头部设计的,并且大小写不敏感,允许使用不同的大小写形式来访问相同的头部字段。
import requests
url = 'http://httpbin.org/get'
response = requests.get(url=url)
# 打印服务器响应的所有头部信息
print(response.headers)
# 直接通过键访问headers字典,如果键不存在则会抛出KeyError异常。
print(response.headers['content-type'])
# 如果键不存在,则不会抛出异常,默认返回None,也可以通过传递第二个参数来设置默认返回值。
print(response.headers.get('content-type'))
# 如果键不存在,返回test。
print(response.headers.get('demo', 'test'))
打印的结果为:
{'Date': 'Sat, 28 Dec 2024 11:57:39 GMT', 'Content-Type': 'application/json', 'Content-Length': '307', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
application/json
application/json
test
3. Cookie
3.1 获取服务器响应的 Cookie
import requests
url = 'http://www.baidu.com'
response = requests.get(url=url)
# 打印服务器响应的所有cookie
print(response.cookies)
# 打印从服务器响应中获取到的名为 'H_PS_PSSID' 的 cookie 的值。
# 如果不存在名为 'H_PS_PSSID' 的 cookie,则会抛出 KeyError 异常。
print(response.cookies['H_PS_PSSID'])
# 如果 cookie 不存在,它将返回 None 或者指定的默认值,而不会抛出异常
print(response.cookies.get('H_PS_PSSID'))
# 如果 cookie 不存在,返回指定的值
print(response.cookies.get('example_cookie_name', 'test_cookie'))
打印的结果为:
<RequestsCookieJar[<Cookie BAIDUID=627BEA4A34524A3DBC559E2D5C068A8A:FG=1 for .baidu.com/>, <Cookie BAIDUID_BFESS=627BEA4A34524A3DBC559E2D5C068A8A:FG=1 for .baidu.com/>, <Cookie BIDUPSID=627BEA4A34524A3DBC559E2D5C068A8A for .baidu.com/>, <Cookie H_PS_PSSID=61027_61216_61429_61444_60853_61508_61518_61524_61538_61362_61607_61627 for .baidu.com/>, <Cookie PSTM=1735387988 for .baidu.com/>, <Cookie BDSVRTM=7 for www.baidu.com/>, <Cookie BD_HOME=1 for www.baidu.com/>]>
61027_61216_61429_61444_60853_61508_61518_61524_61538_61362_61607_61627
61027_61216_61429_61444_60853_61508_61518_61524_61538_61362_61607_61627
test_cookie
3.2 向服务器发送 Cookie
要向服务器发送 cookie,可以使用 cookies
参数传递一个字典或者直接传递一个 RequestsCookieJar
对象。
3.2.1 使用 cookies 参数传递一个字典
import requests
url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working')
# cookies = {'cookies_are': 'working'}
response = requests.get(url=url, cookies=cookies)
print(response.text)
打印的结果为:
{
"cookies": {
"cookies_are": "working"
}
}
4. 重定向
默认情况下,除了 HEAD 请求外,requests
会自动处理所有的重定向。可以使用 Response.history
来追踪重定向的历史记录,它是一个按照从最老到最近排序的 Response
对象列表。
4.1 查看重定向历史记录
GitHub 会将所有 HTTP 请求重定向到 HTTPS。
import requests
url = 'http://github.com'
response = requests.get(url=url)
# 打印url
print(response.url)
# 打印重定向记录
print(response.history)
打印的结果为:
https://github.com/
[<Response [301]>]
从打印结果可以看到 github 的 http 请求被重定向到了 https。
4.2 禁用重定向
可以通过设置 allow_redirects=False
来禁用自动重定向处理。
import requests
url = 'http://github.com'
# 设置 allow_redirects=False,表示禁用重定向
response = requests.get(url=url, allow_redirects=False)
print(response.url)
print(response.status_code)
print(response.history)
打印的结果为:
http://github.com/
301
[]
4.3 启用 HEAD 请求的重定向
对于 HEAD 请求,默认情况下不会跟随重定向,可以显式地启用它。
import requests
url = 'http://github.com'
# 设置 allow_redirects=True,表示启用重定向
response = requests.head(url=url, allow_redirects=True)
print(response.url)
print(response.history)
打印的结果为:
https://github.com/
[<Response [301]>]
5. 超时
为了避免程序因等待响应而无限期挂起,可以使用 timeout
参数指定一个超时时间(以秒为单位)。如果服务器在这个时间内没有响应,requests
将抛出一个 Timeout
异常。
import requests
url = 'http://github.com'
response = requests.get(url=url, timeout=0.001)
6. 错误与异常
当遇到网络问题(如 DNS 查询失败、拒绝连接等)时,requests
会抛出 ConnectionError
异常。如果 HTTP 请求返回了不成功的状态码,Response.raise_for_status()
会抛出 HTTPError
异常。其他可能抛出的异常包括但不限于 Timeout
(请求超时)、TooManyRedirects
(超过最大重定向次数)。所有由 requests
显式抛出的异常都继承自 requests.exceptions.RequestException
。