requests基础
requests的作用:
发送网络请求,返回相应数据
解决编码乱码问题,方法如下:
response=requests.get('url') #rqs库里面的get()方法
print(response.content.decode()) #获取网页内容,将字节B转化成字符串显示用decode()方法
#如果不是utf-8,可以用response.content.decode('gbk'),在括号里写上编码格式就可以了
response.encoding = 'utf-8'
print(response.text) #修改编码格式,获取网页内容
response.text和response.content的区别
response.text(文本属性):
- 返回 str 类型
- 修改编码方式 response.encoding = 'utf-8'
response.content(内容属性,获取音频、视频、图片数据为主):
- 返回 Bytes 类型
- 修改编码方式 response.content.decode() or response.content.decode('utf-8')
获取状态码
对象.status_code #对象.属性
print(response.status_code) #对象.属性
获取请求头 (浏览器向服务器获取的请求)
print(response.request.headers)
获取结果:
{'User-Agent': 'python-requests/2.28.1',
'Accept-Encoding': 'gzip, deflate',
'Accept': '*/*',
'Connection': 'keep-alive'}
不难发现,这是一个爬虫 python-requests/2.28.1 ,所以要学会伪装【我写的《爬虫简单实操1——爬取一张豆瓣图片>》里面有详细提到关于UA伪装】
获取服务器返回给浏览器的内容
print(response.headers)
获取结果:
{'Date': 'Thu, 26 Jun 2025 05:02:13 GMT',
'Content-Type': 'text/html; charset=utf-8',
'Transfer-Encoding': 'chunked',
'Connection': 'keep-alive',
'Keep-Alive': 'timeout=30',
'X-Xss-Protection': '1; mode=block',
'X-Douban-Mobileapp': '0',
'Expires': 'Sun, 1 Jan 2006 01:00:00 GMT',
'Pragma': 'no-cache',
'Cache-Control': 'must-revalidate,
no-cache, private', 'X-DAE-App': 'movie',
'X-DAE-Instance': 'default',
'Set-Cookie': 'bid=3jTkaw1loAw; Expires=Fri, 26-Jun-26 05:02:13 GMT; Domain=.douban.com; Path=/',
'X-DOUBAN-NEWBID': '3jTkaw1loAw',
'Server': 'dae',
'X-Content-Type-Options': 'nosniff',
'Content-Encoding': 'gzip'}
能够和F12里面参数对应上
爬取一张豆瓣图片,并保存到本地(《爬虫简单实操1——爬取一张豆瓣图片>》里也会细讲)
import requests
response=requests.get('https://img2.doubanio.com/view/photo/s_ratio_poster/public/p2920268831.webp')
#保存到本地
with open('罪人.png','wb') as f: # 写清楚 “保存的图片名” 和 “写入的方式”
f.write(response.content)
伪装-headers
url = 'xxx'
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.462.400 QQBrowser/13.3.6197.400'}
response = requests.get(url,headers=headers)
发送带参数的请求
https://www.baidu.com/s?wd=python&rsv_spt=1
https://www.zhihu.com/question/430556643/answer/72276786115
不一定都是请求的路径,比如知乎网站,我们能清晰的分辨哪些是参数
参数的形式:字典
kw = {'wd':'python'}
用法:requests.get(url,params=kw)
可以通过输出url检查是否把参数传入
用法:对象.request.url
print(response.request.url)
import requests
url = 'https://www.baidu.com/s?' #这里的参数我在字典里面写了传过去就行了
kw = {'wd':'python'}
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36 Core/1.116.462.400 QQBrowser/13.3.6197.400'}
response=requests.get(url,params=kw,headers=headers)
print(response.content.decode())
print(response.text) #两个都行
注意:百度现在不可以爬取搜索页面,记得robots协议吧,访问会跳转到百度安全验证,是百度的人机验证
不要暴力破解:可能导致 IP 永久封禁。
遵守 robots.txt:百度禁止爬虫抓取 /s?wd= 搜索结果页。
法律风险:绕过验证码可能违反《数据安全法》,建议评估需求合法性。
所以我们带着这个知识点爬取 豆瓣 的数据吧!
import requests
url = 'https://search.douban.com/movie/subject_search?' #%E5%93%88%E5%88%A9%E6%B3%A2%E7%89%B9 是哈利波特
kw = {
'search_text':'哈利波特', #输入文字,网页会自动帮我们转为URL 编码(URL Encoding),也称为 百分号编码(Percent-Encoding),它的作用是为了让中文、特殊字符等能在URL里安全传输,避免解析错误。
'cat':'1002'
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
response = requests.get(url, params=kw,headers=headers)
response.encoding = 'uft-8'
print(response.request.url) # 检查是否返回正常页面
输出结果:
https://search.douban.com/movie/subject_search?search_text=%E5%93%88%E5%88%A9%E6%B3%A2%E7%89%B9&cat=1002
点击可以跳转到搜索 “哈利波特” 电影的页面
更新一下代码,输入想查询的电影,之后可能会接着更新加个可视化搜索窗口啥的:
import requests
movies=input('输入你想查询的电影:\n')
url = 'https://search.douban.com/movie/subject_search?' #%E5%93%88%E5%88%A9%E6%B3%A2%E7%89%B9 是哈利波特
kw = {
'search_text':movies,
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
response = requests.get(url, params=kw,headers=headers)
response.encoding = 'uft-8'
print(response.request.url) # 检查是否返回正常页面
with open(movies+'.html','w') as f:
f.write(response.text)
要注意的是,这个保存下来的网页代码能打开对应的页面,但是由于豆瓣的部分数据是在本地渲染出来的,所以网页打开会非常缓慢。(如果用代码保存下来的网页乱码,就自己print(response.text) 代码复制下来,自己生成一个html文件吧)
requests深入
发送post请求
什么时候会用到post请求:
1 登陆注册(post比get更安全),主要原因如下:
因此,登录、注册等涉及敏感信息的操作,必须使用 POST 请求,并配合 HTTPS 等其他安全措施。
2 需要传输大文本的时候(post请求对数据长度没有要求)
爬虫也需要在这两个地方模拟浏览器发送post请求,用法如下:
import requests
url = 'https://www.youkuaiyun.com/?spm=1011.2415.3001.4476'
data = {}
headers = {}
response = requests.post(url,data=data,headers=headers)
data的形式:字典
以百度翻译为例
我们提交了“hello”,抓包就看是post方法的数据,把post都找一下看一下到底哪个是我们需要的数据,这个数据是json类型
百度不肯给我们响应数据
有道也试了,有道的数据是html,不是json,可以通过传参获取内容,但是获取的内容要从html里面去获取,比json麻烦,要去取标签里面的内容。
项目进展不下去了,翻译功能不让我看,就写一下json的思路吧
1、通过【响应】找到正确的post数据的位置,这里找到了翻译过来的“你好”,然后我们就可以看它的【参数】有哪些,也就是发送的【请求】有哪些
可以看到,请求的【参数】内容非常多
2、如果PC端 F12给的【参数】太多了,可以调整到手机端查看,发现参数少了很多!
要注意用手机端的话,一些数据需要调整一下,比如url,data,headers
3、json有乱码可以在网上找解析工具解析,看是否解析出想要的内容。我想要hello下面生成的这些单词解释,这个是可以看到响应数据的
这个是可以看到响应数据的,所以我找到了对应的post的数据
通过网上json解析工具解析,发现数据是我要的
4、取json里面的值
先看下输出的值是什么类型,确定是字典dict才好进行取值
result = response.content.decode()
print(type(result))
输出结果:<class 'str'>
结果是str类型,那么需要导入json模块,将字符串转换成字典类型
import json
result = json.loads(result) #用json.loads() 将字符串转换成字典类型,因为json是字典类型数据
print(type(result))
输出结果:<class 'dict'>
现在可以用字典的方法取出数据,字典内容如下:
{
"errno": 0,
"data": [
{
"k": "hello",
"v": "int. 打招呼; 哈喽,喂; 你好,您好; 表示问候 n. “喂”的招呼声或问候声 vi. 喊“喂"
},
{
"k": "hellos",
"v": "n. 喂( hello的名词复数 )"
},
{
"k": "hellow",
"v": "(通常的招呼语)嗨, (打电话用)喂!, (英)(表示惊讶)哎哟"
},
{
"k": "hello girl",
"v": "女话务员; 女电话接线员"
},
{
"k": "hello kitty",
"v": "n. 卡通世界中; 有这样一只小猫; 没有嘴巴; 脸蛋圆圆的"
}
],
"logid": 668793641
}
我想要每个中文翻译,而这个字典嵌套列表,列表里面嵌套字典元素,我要的中文在列表里面由好几个字典元素构成,所以取法可以是 result[‘data’][0][‘v’]…result[‘data’][4][‘v’],最容易思考出来的方法是for循环。
result = result['data'] #这是一个列表,里面有很多字典元素
for i in result:
print(i['v']) #str类型
#列表推导式取值
#print([item["v"] for item in result['data']])
用AI查询还有其他的【字典嵌套列表嵌套字典】取值的好用办法,最好用的还是列表推导式:
最后,方法学会了就行!整体代码如下:
import requests
import json
url = 'https://fanyi.baidu.com/sug'
data ={
'kw':"hello"
}
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0',
'Host':'fanyi.baidu.com'
}
response = requests.post(url,data=data,headers=headers)
result = response.content.decode()
# print(type(result)) #<class 'str'>,字符串类型不好取,所以字符串转化成字典类型(用json),先导入json模块
result = json.loads(result) #用json.loads()将字符串转换成字典类型,因为json都是字典类型
# print(type(result))
result = result['data'] #这是一个列表,里面有很多字典元素
for i in result:
print(i['v']) #str类型