文章目录
- 发送请求
- 响应对象
- 响应数据的方式
- 中文乱码问题
- 响应对象的其他属性或方法
- 发送带参数的请求
- headers和查询参数
Requests——发送http请求,获取响应数据
首先,请确保:
- 已安装 Requests
- Requests 是最新的
让我们从一些简单的示例开始。
发送请求
使用 Requests 发出请求非常简单。
需求:通过requests想百度首页发送请求,获取该页面的源码
运行下面的代码,观察打印出的结果
#首先导入Requests模块:
import requests
# 目标url
url = 'https://www.baidu.com'
# 向目标url发送get请求
response = requests.get(url)
# 打印响应内容
print(response.text)
其他HTTP类型呢:PUT,DELETE,HEAD?这些都是同样的:
response = requests.post(url,data = {'key' : 'value'})
response = requests.put(url,data = {'key' : 'value'})
response = requests.delete(url)
response = requests.head(url)
response = requests.options(url)
这一切都很好,但这也只是 Requests 可以做到的开始 !
响应对象
响应数据的方式
当你使用 requests
库发送一个请求(例如 requests.get()
或 requests.post()
等)时,服务器会返回一个响应。这个响应包含了很多信息,而 requests.text
和 response.content
就是从这个响应中获取数据的常见的两种不同方式。
requests.text
:
它是从响应中提取的数据经过解码后的结果,是一个字符串(Unicode 字符串)。这个解码过程通常是根据服务器在 Content-Type
头部信息中提供的字符编码进行的,如果服务器没有明确给出字符编码,requests
库会尝试使用 chardet
库来猜测编码方式,然后将响应数据从字节(bytes)解码为字符串。例如,如果服务器返回的是一个 HTML 页面,你可以直接使用 requests.text
来获取这个页面的文本内容,以便后续使用 BeautifulSoup
或其他文本处理工具进行解析。
response.content
:
它是服务器返回的原始字节数据,也就是最原始的响应数据,没有经过任何解码处理。这对于处理二进制数据非常有用,例如当你从服务器下载一个文件(如图像文件、音频文件、视频文件、压缩文件等)时,你需要使用 response.content
来获取这些文件的原始字节,以便将其保存到本地或进行其他二进制处理操作。
requests.text和response.content的区别
对比维度 | requests.text | response.content |
---|---|---|
数据类型 | 解码后的 Unicode 字符串 | 原始字节数据(bytes 类型) |
编码处理 | 根据 HTTP 头部字符编码信息(或 chardet 模块猜测)自动解码 | 不进行编码解码,直接返回原始字节 |
适用场景 | 处理文本数据,如解析 HTML、JSON、XML 等 | 处理二进制数据,如图片、视频、音频、压缩文件等 |
获取方式 | 直接获取解码后的文本内容 | 获取原始字节内容,需手动解码(若为文本) |
应用示例 | 使用 BeautifulSoup 解析 HTML 网页:soup = BeautifulSoup(response.text, ‘html.parser’) | 保存图片到本地:with open(‘image.png’, ‘wb’) as f: f.write(response.content) |
【代码示例】
import requests# 发送请求
response = requests.get('https://example.com')# 使用 requests.text 获取解码后的文本数据
text_data = response.text
print("Text Data:", text_data[:100]) # 打印前 100 个字符的文本内容# 使用 response.content 获取原始字节数据
content_data = response.content
print("Content Data:", content_data[:100]) # 打印前 100 个字节的数据'''运行结果:
Text Data: <!doctype html>
<html>
<head><title>Example Domain</title><meta charset="utf-8" /><m
Content Data: b'<!doctype html>\n<html>\n<head>\n <title>Example Domain</title>\n\n <meta charset="utf-8" />\n <m'
'''
中文乱码问题
当你使用 requests
库发送请求并接收到服务器的响应时,response.content
是以字节(bytes)形式存储的数据。如果该数据包含中文字符,而你直接使用 response.content
查看或处理这些数据,可能会出现中文乱码的情况。这是因为你需要将字节数据按照正确的编码方式解码为字符串,这样才能正确显示中文。以下是解决中文乱码问题的具体步骤:
一、检查服务器响应的编码方式
首先,你可以查看服务器响应的 Content-Type
头部信息,其中可能包含了编码信息。你可以通过 response.encoding
或者 response.headers.get('Content-Type')
来获取这些信息。例如:
import requestsresponse = requests.get('https://example.com')
print("服务器响应的编码方式(通过 encoding 属性):", response.encoding)
print("服务器响应的编码方式(通过 headers):", response.headers.get('Content-Type'))'''运行结果:
服务器响应的编码方式(通过 encoding 属性): ISO-8859-1
服务器响应的编码方式(通过 headers): text/html
'''
通过上述代码,你可以获取服务器声明的编码方式。然而,有时候服务器可能没有正确声明编码,或者声明的编码与实际的编码不符,这时就需要手动指定编码进行解码。
二、使用 decode 方法进行解码
你可以使用 response.content.decode()
方法对字节数据进行解码。如果你知道服务器使用的正确编码方式,就可以直接将其作为参数传递给 decode
方法。例如,如果服务器使用的是 utf-8
编码:
import requestsresponse = requests.get('https://example.com')
decoded_content = response.content.decode('utf-8')
print(decoded_content)
在这个例子中,response.content.decode('utf-8')
会将字节数据按照 utf-8
编码方式解码为字符串,这样就能正确显示中文。
通过对response.content进行decode,来解决中文乱码
response.content.decode()
默认UTF-8response.content.decode("GBK")
- 常见的编码字符集
- UTF-8
- gbk
- gb2312
- ascii
- iso-8859-1
三、自动猜测编码并解码(使用 chardet)
如果不确定服务器的编码方式,可以使用 chardet
库来猜测编码。chardet
可以分析字节数据并尝试确定最可能的编码。以下是一个使用 chardet
的示例:
import requests
import chardetresponse = requests.get('https://example.com')
# 使用 chardet 检测编码
detected_encoding = chardet.detect(response.content)['encoding']
print("检测到的编码:", detected_encoding)
# 按照检测到的编码进行解码
decoded_content = response.content.decode(detected_encoding)
print(decoded_content)
在这个例子中:
- 首先,使用
chardet.detect(response.content)
对response.content
进行编码检测。 chardet.detect(response.content)['encoding']
会返回检测到的编码。- 最后,将检测到的编码作为参数传递给
decode
方法对字节数据进行解码。
【完整代码示例】
import requests
import chardetdef get_decoded_content(url):response = requests.get(url)try:# 尝试使用服务器声明的编码进行解码decoded_content = response.content.decode(response.encoding)except UnicodeDecodeError:# 若解码失败,使用 chardet 猜测编码detected_encoding = chardet.detect(response.content)['encoding']decoded_content = response.content.decode(detected_encoding)return decoded_content# 示例使用
url = 'https://example.com'
decoded_content = get_decoded_content(url)
print(decoded_content)
响应对象的其他属性或方法
除了text和status_code以外,response响应对象还有其他常用的属性或方法
属性或方法 | 说明 |
---|---|
response.url | 响应的url,有时候响应的url和请求的url并不一致 |
response.status_code | 响应状态码 |
response.request.headers | 响应对应的请求头 |
response.headers | 响应头 |
response.request._cookies | 响应对应请求的cookie,返回cookieJar类型 |
response.cookies | 响应的cookie(经过了set-cookie动作,返回cookieJar类型) |
response.json() | 自动将json字符串类型的响应内容转换为python对象(dict/list) |
【代码示例】
import requests
# response = requests.get('https://example.com')
# print(response.status_code)
# print(response.headers) # 可以查看响应的头部信息
# print(response.headers.get('Content-Type')) # 可以获取具体的 Content-Type 信息,对于后续处理不同类型的响应内容很有用
# print(response.encoding) # 提供编码信息,有时可能不准确
# print(response.cookies) # 可以查看服务器返回的 Cookie 信息response = requests.get('https://api.example.com/data')
data = response.json()
print(data) # 将响应内容解析为 JSON 格式
发送带参数的请求
我们在使用百度的时候经常发现url地址中会有一个
?
,那么该问号后边的就是请求参数,又叫做查询字符串
headers和查询参数
如果想添加 headers,可以传入headers
参数来增加请求头中的headers信息。如果要将参数放在url中传递,可以利用 params
参数。
(一)在url携带参数
直接对含有参数的url发起请求
url = 'http://www.baidu.com/s?wd=长城'
response = requests.get(url, headers = headers)
(二)通过params携带参数字典
- 构建请求参数字典
- 向接口发送请求的时候带上参数字典,参数字典设置给params
【代码示例】
import requestsurl = 'http://www.baidu.com/s?'
# 添加请求头,进一步伪装浏览器
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
# 构建参数字典
kw = {'wd':'长城'
}
# params 接收一个字典或者字符串的查询参数,字典类型自动转换为url编码,不需要urlencode()
response = requests.get("http://www.baidu.com/s?", params = kw, headers = headers)# 查看响应内容,response.text 返回的是Unicode格式的数据
print (response.text)# 查看响应内容,response.content返回的字节流数据
print (respones.content)# 查看完整url地址
print (response.url)# 查看响应头部字符编码
print (response.encoding)# 查看响应码
print (response.status_code)