request用法_request库的高级用法

高级用法

在之前的文章我们了解过requests库的基本用法,如基本的GET、POST请求以及Response对象。本文介绍requests库的一些高级用法,如文件上传Cookies设置代理设置等。

1.文件上传

requests可以模拟提交一些数据,假如有的网站需要上传文件,我们也可以用它来实现,这非常简单。

实例展示:

import requests

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

d3decb8e657b3de7f11d7e144d058c09.png

输出结果:

5bd17922b99d060e47a4ec1a81d5a7ca.png

7d6e1c8172b5e3fd1da63b3c91b9604f.png

上一篇文章中,我们获取了一个github的图标文件favicon.ico,这里用它来模拟文件上传的过程,注意上传的文件需要和当前脚本在同一目录下,如果有其他文件,当然也可以使用其他文件来上传,更改下代码即可。

2.Cookies

使用requests库可以一步完成获取和设置Cookies,相对于urllib库十分简便。

实例展示:

import requests

r = requests.get("http://www.baidu.com")
print(r.cookies)
print(r.cookies.items())

for key,value in r.cookies.items():
 print(key + '='+value)

74f2b7f27af600c88a3bfa9066e08c35.png

输出结果:

8bb5e13b3f6d82659ff41e13ce0e5bb0.png

上面代码中,我们首先调用cookies属性即可成功获取网页的Cookies,它是一个RequestCookieJar类型。然后用items()方法,将其转化为元组组成的列表,用for循环,遍历输出每一个Cookie的名称和值。

我们还可以直接用Cookie来维持登陆状态,下面以知乎为例说明,首先登陆知乎,用开发者工具将Headers中的Cookie和User-Agent内容复制下来。

8bd8bb2c32a9db7e477431155d1988cb.png

接下来,将其设置到Headers里面(自己试的时候换成自己的Cookie),然后发送请求。

示例如下:

import requests

headers = {
 'cookie':'你的Cookie',
 'user-agent':'你的user-agent'
}

r = requests.get("https://www.zhihu.com",headers=headers)
print(r.text)

f16bbec33d0a969b8b1cdeb739710a9d.png

输出结果:

41251c6740ac862a9de41e9262b4d782.png

还有一种方法,可以通过cookies参数来设置,不过这样需要构造RequestsCookieJar对象,而且需要分割一下cookies,相对繁琐。

示例如下:

cookies = '你的Cookie'

jar = requests.cookies.RequestsCookieJar()
headers = {
 'user-agent':'你的user-agent'
}

for cookie in cookies.split(';'):
    key,value = cookie.split('=',1)
    jar.set(key,value)
r = requests.get("https://www.zhihu.com",cookies=jar,headers=headers)
print(r.text)

9588cffae62efcb93addc451a5a53564.png

输出结果:

da6e59dc912ab4c2a5efab002b434466.png

3.会话维持

在requests中,如果直接利用get()或post()等方法,的确可以做到模拟网页的请求,但这实际上是不同的会话,相当于用两个浏览器打开了不同页面。

设想一个场景,第一次请求利用POST方法登陆了某个网站,第二次想获取成功登陆后的自己的个人信息,你又用了一个get()方法去请求个人信息页面,实际上着相当于打开了两个浏览器、是两个完全不相关的会话,不能成功获取个人信息。

要解决这个问题,主要的方法是维持同一个会话,相当于打开一个新的浏览器选项卡,而不是新开一个浏览器,但我又不想每次都设置cookies,这会比较繁琐。Session对象可以解决这个问题。

实例展示:

import requests

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

4d6abe52eeaecee78cf0255741d70189.png

输出结果:

8f92ebf9e1c4e303b30cea7a86485dd4.png

这里我们请求了一个测试网站:"http://httpbin.org/cookies/set/number/123456789"。请求这个网站时,可以设置一个cookie,名称叫做number,内容是123456789,随后又请求了"http://httpbin.org/cookies",此网址可以获取当前的Cookies。

从输出结果,我们发现并没有成功获得Cookies

下面我们通过构建Session对象再试试

import requests
s = requests.Session()#构建Session对象
s.get("http://httpbin.org/cookies/set/number/123456789") 
r = s.get("http://httpbin.org/cookies")
print(r.text)

844a1314b225c616d420dd07bfb299b1.png

输出结果:

f5ca8ce7d7261da8ec3b1f459d9b8920.png

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

session的用使用范围非常广泛,可以用于模拟在一个浏览器中打开同一站点的不同页面,后面会有专门的章节来讲解这部分内容。

4.SSL证书验证

requests还提供证书验证功能,当发送HTTP请求的时候,它会检查SSL证书,我们可以使用verify参数控制是否检查此证书。 verify参数默认是True,会自动验证。

原来12306的证书没有被官方CA机构信任,会出现证书验证错误结果(现在已经没有这个问题了)

我们还是以它举例,如果要跳过SSL验证的话,只需要把verify参数设置为False即可

示例如下:

import requests

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

66ddb73d9b8046beb1a328560ecd3635.png

输出结果:

80fc2ee733452851d02616a57967a5d4.png

输出结果中,带有警告,可以通过以下两种方法来屏蔽或忽略警告。

【1】设置忽略警告

import requests
from requests.packages import urllib3

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

输出结果:

f95316adf0e7259992765251bee8658d.png

【2】捕获警告到日志

import requests
import logging

logging.captureWarnings(True)
r = requests.get("https://www.12306.cn",verify = False)
print(r.status_code)

输出结果:

f95316adf0e7259992765251bee8658d.png

还可以指定一个本地证书作为客户端证书,这里我们就不详细讲了。

5.代理设置

对于某些网站,在测试的时候请求几次,就能正常获取内容。但一旦开始大规模爬取,对于大规模且频繁的请求,网站可能会弹出验证码,或者跳转到登陆验证页面,更有甚者可能会直接封禁客户端IP,导致一段时间无法访问。

所以为了防止单个ip频繁访问,导致弹出验证或封禁,我们需要设置代理IP来解决这个问题,这里需要用到proxies参数。

设置如下:

import requests

proxies = {
 "http":"183.195.106.118:8118"
}

requests.get("https://www.taobao.com",proxies = proxies)

f1a17d231db7c7124a041f7e9a59a290.png

上面的代码不能直接运行,因为里面的代理可能是无效的,可以换成自己的有效代理试试。

如果代理需要使用到HTTP Basic Auth,可以使用类似http://user:password@host:port这样的语法来设置代理:

import requests

proxies = {
 "http":"http://user:password@183.195.106.118:8118"
}

requests.get("https://www.taobao.com",proxies = proxies)

10b918ffa9b62136d12fb9c4c854dc87.png

除了基本的HTTP代理外,requests还支持SOCKS协议的代理。

首先,需要安装socks这个库:

pip3 install requests[socks]

然后就可以使用SOCKS协议代理了,示例如下:

import requests

proxies = {
 "http":"socks5://user:password@host:port"
}

requests.get("https://www.taobao.com",proxies = proxies)

eef6430820c2ffe2116571f453614704.png

6.超时设置

前面在urllib讲过,在网络状态不好等原因下,可能长时间无法获得响应,应该设置一个超时时间,超过这个时间没有得到响应就报错,也就是借助timeout参数。

示例如下:

import requests


r=requests.get("https://www.taobao.com",timeout= 1)
print(r.text)

4d335404fb0508279494101def4bb6ff.png

通过上述设置,我们可以将超时时间设置为1秒,如果1秒中没有响应,就抛出异常,当然实际过程中可以根据需求设置。

实际上,请求分为两个阶段,即连接(connect)和读取(read)

timeout=设置的是两者时间的总和,如果要分别指定,可以传入一个元组。

示例如下:

import requests


r=requests.get("https://www.taobao.com",timeout= (3,3))
print(r.text)

如果想永久等待,timeout默认为None,直接不设置即可。

7.身份验证

在访问网站时,如果遇到需要进行身份验证,可以采用以下的简便方法

示例:

import requests


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

9c16782f6bf75ced1f781c9b69647766.png

8.Prepared Request

在urllib中,我们可以将请求表示为数据结构,各参数通过Request对象来表示,在requests里同样可以做到,这个数据结构叫Prepared Request。

实例展示:

from requests import Request,Session

url = "http://httpbin.org/post"

data ={
 'name':'germey'
}

headers = {
 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
}

s=Session()
req = Request('POST',url,data=data,headers=headers)
prepped = s.prepare_request(req)
r = s.send(prepped)
print(r.text)

d0487658941ed52485f0fa86eac521e1.png

这里我们引入了Request,然后用url、data、headers参数构造了一个Requset对象,这时需要调用Session的prepare_request()方法将其转换为一个Prepared Request对象,然后调用send()方法发送即可。

输出结果:

e82b9b4d4dca9bb012208e93f8a807f8.png

从结果可以看到,我们成功获取了POST请求。

更多的用法或者问题,可以参考requests的官方文档:(https://requests.readthedocs.io/zh_CN/latest/user/advanced.html)

本文总结参考《Python3网络爬虫开发实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`request_firmware_nowait` 和 `request_firmware` 都是 Linux 内核中的函数,用于请求加载固件文件。它们的主要区别在于是否使用异步方式加载固件: - `request_firmware_nowait` 函数使用异步方式加载固件,即请求后立即返回,固件加载完成后会通过回调函数通知调用者。这种方式适用于不需要等待固件加载完成就可以继续执行的场景。 - `request_firmware` 函数使用同步方式加载固件,即请求后会一直等待固件加载完成后才会返回结果。这种方式适用于需要等待固件加载完成后才能继续执行的场景。 它们的用法如下: ```c int request_firmware_nowait(struct firmware **firmware_p, const char *name, struct device *device, gfp_t gfp_flags, void *context, size_t size, void (*cont)(const struct firmware *fw, void *context)); int request_firmware(struct firmware **firmware_p, const char *name, struct device *device); ``` 其中,`firmware_p` 是输出参数,用于获取加载后的固件数据;`name` 是固件文件名;`device` 是请求加载固件的设备;`gfp_flags` 是内存分配标志;`context` 是传递给回调函数的上下文参数;`size` 是固件数据的长度(仅在异步方式下有效);`cont` 是回调函数,用于在异步方式下通知固件加载完成。 需要注意的是,请求加载固件文件需要在 Linux 内核中的进程上下文中进行,因此在中断上下文中无法使用这两个函数。如果需要在中断处理程序中加载固件,可以使用 `request_firmware_direct` 函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值