requests模块

本文详细介绍了Python的requests模块,包括GET、POST请求,响应内容的处理,会话维持,SSL证书验证,代理设置,超时设置,身份验证等高级用法。示例代码展示了如何获取网页内容、爬取二进制数据、处理Cookies和维持会话等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用requests

了解了urllib的基本用法,但是其中确实又不方便的地方,比如在处理网页验证和cooki时,需要写Opener和Hander来处理器,而reuqests方法对于解决Cookies,登录操作,代理设置等操作有很大的帮助。

基本用法

实例引入
urllib库中的urlopen()方法实际上是以GET方式请求网页,而requests中相应的方法就是get()方法。

import requests

r = request.get('https://www.baidu.com/')
print(type(r))
print(r.status_code)
print(type(r.text))
print(r.text)
print(r.cookies)

运行结果如下:

<class 'requests.models.Response'>
200
<class 'str'>
#...text部分被省略
<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>

这里我们调用get()方法实现了与urlopen()相同的操作,得到了一个Response对象,然后分别输出了Responce的类型,状态码,响应体的类型,内容以及Cookies。
通过运行结果发现他的返回类型,是requests.models.Response,响应体的类型是字符串str,Cookies的类型是RequestsCookieJar。
使用get()实现了一个GET请求,

r = requests.post('http://httpbin.org/post')
r = requests.put('http://httpbin.org/put')
r = requests.delete('http://httpbin.org/delete')
r = requests.head('http://httpbin.org/get')
r = requests.options('http://httpbin.org/get')

这里分别用post(),put(),delete()等方法实现了POST,PUT,DELETE等请求。

responce.text和responce.content的区别

responce = requests.get(url)
respnoce的常用方法:

responce.text
responce.content
responce.status_code
responce.request,
responce.headers

responce.text和responce.content的区别

responce.text
类型:str
解码类型:根据HTTP头部对相应的编码做出有根据的推测,
如何修改编码方式:responce.encoding=‘gbk’

responce.content
类型:bytes
解码类型;没有指定
如何修改编码方式:responce.content.decode(‘utf-8’)

两者的区别在于,content中间存的是字节码,而text存在的是根据推测的编码方式将content内容编码成字符串。

如果对于纯ascll码,这两个可以说是一模一样,对于其他的文字,需要正确的编码才能正常显示。
所以可以做出以下总结:1.text()函数可以根据字节的格式来推测编码,输出对应的字符串,而content()函数就是
输出字节,我们可以手动的定义编码格式为:content.decode(‘utf-8’),同样的我们也可以通过提前修改编码。
来使用responce.encode(‘utf-8’)
使用方法如下:

responce = responce.get('url')
responce.encodeing = 'utf-8'
responce.text
##########################
responce.content.decode('utf-8')

2.GET请求
先给一个实例

import requests

r = requests.get('http://httpbin.org/get')
print(r.text)

输出结果如下:

{
  "args": {}, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.21.0"
  }, 
  "origin": "60.168.149.14, 60.166.148.13", 
  "url": "https://httpbin.org/get"
}

我们成功的发起了GET请求,返回结果包含请求头,URL,IP等信息。
那么对于GET请求,如果要添加额外的信息,一般要怎么添加呢?比如我们要加入的是name是germey,age是22.要构造这个请求链接。
可以直接写为:
r = requests.get(‘http://httpbin.org/get/name=germey&age=22’)
这样可以当是不是那么的规整。
我们可以通过字典开存储信息。利用params这个参数。

import requests

data={
	'name':'germey'
	'age':'22'
}
r = requets.get('http://httpbin.org/get',params=data)
print(r.text)

输出结果为:

{
  "args": {
    "age": "22", 
    "name": "germey"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.21.0"
  }, 
  "origin": "XXXXX", 
  "url": "https://httpbin.org/get?name=germey&age=22"
}

可以观察到请求的链接自动被构造成了:我们想要的URL
网页的返回结果其实手是str类型的但是他很特殊是JSON格式的,如果想要解析返回结果得到字典的格式的话可以直接调用json()方法。

import requests

r = requests.get('http://httpbin.org/get')
print(type(r.text))
print(r.json())
print(type(r.json()))

输出结果为:

<class 'str'>
{'args': {}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.21.0'}, 'origin': '60.168.149.14, 60.168.149.14', 'url': 'https://httpbin.org/get'}
<class 'dict'>

可以发现调用json方法,就可以将返回的结果是JSON格式的字符串转化为字典
注意如果返回结果不是JSON格式,便会出现解析错误,爬出json.decoder.JSONDecodeError()异常。

爬取网页

上面的请求链接返回的是JSON形式的字符串,那么如果请求普通的网页,则坑定能获得相应的内容。

import requests
import re

headers ={
    "User-Agent":'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0'
}
r = requests.get('https://www.zhihu.com/explore', headers=headers)
pattern = re.compile('explore-feed.*?question_link.*?>(.*?)</a>', re.S)
titles = re.findall(pattern, r.text)
print(titles)

运行结果如下:

['\n你们在高中发生的全校轰动的事是什么?\n', '\n国产恐怖游戏《纸人》涉及了哪些民俗?\n', '\n如何评价浅色回忆关于rpg游戏的言论?\n', '\n情侣之间如何才能每天过得很甜?\n', '\n如何评论李安琪综艺节目全程英文招致非议?\n', '\n为什么追张云雷有种看爽文的感觉?\n', '\n刚刚玩 CSGO,很疑惑为什么上千元一把刀都有人买?\n', '\n女孩子怎么变得有气质大方?\n', '\n关于《龙族》,有哪些打动你的情节?\n', '\n有没有一些简单好吃又健康而且适合在家做的甜品?\n']

爬取二进制数据

我们一般爬取的页面都是一些HTML文档,如果想要抓取图片,音频,视频等文件,应该怎么办。
图片,音频,视频这些文件本质都是二进制码组成的,由于特定的保存格式和对应的解析方式,我们才可以看到各种各样的多媒体,所以想要爬取这些信息,就要拿到他们的二进制码。
下面爬取的是GitHub的站点图表。

import requests

r = requests.get('https://github.com/favicon.ico')
print(r.text)
print(r.content)

由于输出太长这里简单描述一下结果,前面两行出现了乱码,后面输出的开始位置有一个"b"证明这是二进制数据
分析:前面的结果是图面直接转化为字符串类型,当然会出现乱码。
接下来就介绍如何保存这些图片。

import requests

r = requests.get('https://github.com/favicon.ico')
with open('XXX.ico','wb') as f:
	f.write(r.content)

同样的音频和视频文件也可以通过这种方式获取。

POST请求

前面我们了解到了最基本的GET请求,另外一种比较常见的请求方式是POST,就把相关信息请求信息返回。

import requests

data = {'name':'germey','age':'2'}
r =requests.post('http://httpbin.org/post', data)
print(r.text)

运行结果如下

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "age": "2", 
    "name": "germey"
  }, 
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Content-Length": "17", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "python-requests/2.21.0"
  }, 
  "json": null, 
  "origin": "60.168.149.14, 60.168.149.14", 
  "url": "https://httpbin.org/post"
}

响应

发送请求后,得到的自然就是响应。在上面实例中,我们使用text和content获取了响应的内容,此外,还有很多属性和方法可以用来获取其他信息,比如状态码,响应头,Cookies等,示例如下:

import requests

r = requests.get('http://www.jianshu.com')
print(type(r.status_code), r.status_code)
print(type(r.headers),r.headers)

往往通过这种方式来获取响应的信息。
requests还提供了一个内置的状态码查询对象,requests.codes.

import requests

r = requests.codes('http://www.jianshu.com')
exit()if not r.status_code == requests.codes.ok else print('successful')
这里会出现一个403错误所以程序返回。

具体每一个的状态在py3 (128页)。

requests 模块的高级用法

1.高级用法包括:文件上传,Cookies设置,代理设置。
1.文件上传
我们知道requests可以模拟提交一些数据。假如有的网站需要上传文件我们也可以通过装这个模块来完成。

import requests

files = {'file':open('XXX.ico','rb')}
r = requests.post('http://www.httpbin.org/post',files=files)
print(r.text)

2.Cookies
前面使用urllib处理过Cookies,写法比较的复杂,而有了requets模块以后就能比价轻松的完成设置的内容了。

import requests

r = requests.get('https://www.baidu.com')
print(r.cookies)
for key,value in r.cookies.items():
	print(key+'='+value)

输出结果如下:

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
BDORZ=27315

这里我们首先调用cookies属性即可完成得到Cookies,可以发现它是RequestcookiesJar类型。然后用items()将数据转化为元组组成的列表,遍历输出每一个Cookies的名称和值,实现Cookie的遍历。


当然,我们也可以直接Cookie来维持登录状态,首先登录知乎,将Headers中的Cookie内容复制下来。
登录知乎后再请求头位置复制Cookie。

import requests

headers = {
	'Cookie': 'XXXX'
	'Host': 'www.zhihu.com'
	'User-Agent':''
}
r = requests('https://www.zhihu.com', headers = headers)
print(r.text)

这里会直接输出你登录页面知乎的样子。
get函数有cookies参数,也可以通过这种方式来添加cookie,不过这样就要构造RequestsCookieJar对象,而且需要分割。

cookies = 'A=XXXX;\
B = XXXXXx;'
jar = requests.cookies.RequestsCookieJar()
headers={
	'Host':'wwww.zhihu.com',
	'User-Agent':'XXXX'
}
for cookie in cookies.split(';')
	key, value = cookie.split('=',1)
	jar.set(key, value)
r = requests.get('http://www.zhihu.com',cookies=jar,headers=headers)
print(r.text)

解析:这里新建一个RequestsCookieJar对象,然后复制下来的cookies,利用split()的方法分割,接着利用set()方法设置好Cookie的key和value,这样以后就不用再headers中加入cookie信息了。

会话维持

在requests中,如果直接利用get()或post()等方法的确可以做到模拟网页的请求,但是这实际上是相当于不同的会话相当于是用两个不同的浏览器打开了不同的页面。
如果想登录某个网站第一次你要进行身份验证,然后获得获取登录之后界面的信息。
解决这个问题的主要方法,就是需要维持同一个会话,也就相当于打开一个新的浏览器选项,而不是新开一个浏览器,但又不想每次设置cookies,这里有了一个新的利器。

import requests

requests.get('http://httpbin.org/cookies/set/number/123456789')
r = requests.get('http://httpbin.org/cookies')
print(r.text)

这里我们请求了一个测试网址’http://httpbin.org/cookies/set/number/123456789,请求这个网址时,可恶意设置一个cookie,名称叫做number,内容为12345679,随后有请求了http://httpbin.org/cookies, 此网址可以获取当前的Cookies。
输出结果为:

{
  "cookies": {}
}

这并不行,用Session试试看:

import requests

s = requests.Session()
s.get('http://httpbin.org/cookies/set/number/123456789')
r = s.get('http://httpbin.org/cookies')
print(r.text)

输出结果:

{
  "cookies": {
    "number": "123456789"
  }
}

成功获取。
所以,利用Session,可以做到模拟同一个会话而不用担心Cookies的问题。他通常用于模拟登陆成功之后再进行下一步的操作。

SSL证书验证

此外,requests还提供了证书验证的功能,当发送HTTP请求的时候,他会检测SSL证书,我们可以通过设置verify参数控制是否检查此证书,不加该参数时,默认为True,会自动验证。

import

responce = requests.get('https://www.12306.cn')
print(responce.status_code)

这是需要检验证书的写法。

import requests

responce = requests.get('https://www.12306.cn', verify=False)
print(responce.status_code)

输出结果状态码尽管是200。但是会出现一个警告。
警告的大概含义就是:建议我们使用证书验证,我们可以通过忽略这种警告方式来屏蔽这个警告。

import requests
import urllib3

urllib3.disable_warnings()
response = requests.get('https://www.12306.cn', verify=False)
print(response.status_code)

这样就不会有警告提醒了会直接输出当前状态码。
当然我们也可以指定一个本地证书用作客户端书,这可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组。

import requests

response = requests.get('http://www.12306.cn', cert=('/path/sever.crt','/path/key'))
print(response.status_code)

我们需要有crt和key文件,并且1指定他们的路径,注意,本地私有证书key必须是解密状态,加密状态的key是不支持的。

代理设置

对于某些网站,在测试的时候请求几次,能获取正常的内容,但是一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出来验证码,或者跳转到登录认证页面,更甚者可能会直接封禁客户端的IP,导致一定时间内无法访问。
那么为了防止这种情况下发生我们需要设置代理来解决这个问题,这就需要用到proxies参数。可以用这样的方式设置。

import requests

proxies = {
	'http:''http://10.10.1.10:3128'
	'https':'http://10.10.1.10.1080'
}
requests.get('https://www.taobao.com',proxies=proxies)

超时设置

微=为了防止服务器不能及时相应应该设置一个超时时间,即超过了这个时间服务器还是为未响应,那就报错。

improt requests
r = requets.get('https:www.taobao.com', timeout=1)
print(r.status_code)

实际上设置的timeout将作用连接和读取这两者的timeout总和。
如果要分别指定就可以传入一个元组。
timeout参数默认为None即一直等待服务器相应不会报错,程序也会一直运行下去。

身份验证

在访问页面时有可能是需要我们登录进行身份验证的。
此时就需要使用requests自带的身份认证功能,实例如下:

import requests
from requests.auth import HTTPBasicAuth

r = requests.get('http://localhost:5000',auth=HTTPBasicAuth('username','password'))
print(r.status_code)

当然,如果参数都传入一个HTTPBasicAuth类,就显得有点繁琐了,所以requests提供了一个更加简单的写法,可以直接传入一个元组,他会默认使用HTTPBasicAuth这个类来认证。
所以上面的代码可以直接简写如下:

import requests

r = requests.get('http://locallhost:5000',auth=('username','password'))
print(r.status_code)

Prepared Request

前面介绍了urllib时我们可以将请求当做是是数据结构,其中各个参数都可以通过一个Request对象来表示,这在requests里面同样可以做到,这个数据结构叫做Prepared Request

from requests import Request, Session
url = 'http://httpbin.org/post'
data = {
	'name':'germy'
}
headers = {
	'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0'
}
s = Session()
req = Request('POST',url,data=data,headers=headers)
prepped=s.prepare_request(req)
r=s.send(prepped)
print(r.text)

这里我们引入例如Request,然后用url,data,和headers参数构造了一个Request对象,这时需要再调用Session和prepare_request()方法将其转化为一个Perpared Request对象,然后调用send()方法发送即可。
相关知识点的官方文档:‘http://docs.python-requests.org

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值