Python 的 requests 是一个简单易用的 HTTP 库,但我之前很少用到它。我开始重视是因为工程师分享给我 Rum Bot 代码中,用到了这个方法来和 api 交互,同时也用到它来爬取和下载图片。
这篇学习笔记汇总了 requests 的基本用法。
安装
执行 import 检查自己本地是否已经安装。如果没有安装,在命令行模式下执行 pip 安装即可。
pip install requests
import requests
各种请求
requests 有多个请求。最常用到的是 get() 和 post(),其它我目前没有用到过。
在 requests 这个库的简介中,也是只举例了 get() 和 post() 这两个方法。
下述 url 也都是 requests 开发者所提供的,大胆尝试。
requests.get('http://httpbin.org/get')
requests.post('http://httpbin.org/post')
requests.put('http://httpbin.org/put')
requests.delete('http://httpbin.org/delete')
requests.head('http://httpbin.org/get')
requests.options('http://httpbin.org/get')
requests.get('http://httpbin.org/get')
这些请求的返回值,是 requests 自定义的一种类型。
resp = requests.get('http://httpbin.org/get')
type(resp)
以 Get() 请求为例,可以看到它具备如下属性:
import requests
url = "http://httpbin.org/get"
resp = requests.get(url)
状态码。200,一般表示正常。其它码值见 api 设计,通常码值含义都是一致的。
#状态码
resp.status_code
type(resp.status_code)
#请求url
resp.url
type(resp.url)
#头信息
resp.headers
type(resp.headers)
h = resp.headers
for k,v in enumerate(h):
print(v,h[v])
头信息的 Connection 很关键,默认是 keep-alive,但有时会导致连接过多,而被目标拒绝访问。可以 update 为 Close:
resp.headers.update({"Connection":"Close"})
resp.headers
#cookies
resp.cookies
type(resp.cookies)
#以文本形式打印网页源码
resp.text
type(resp.text)
#以字节流形式打印
resp.content
type(resp.content)
字节流有个很好的用途。
比如:利用字节流下载并保存图片
import requests
url = "https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"
picname = url.split("/")[-1]
picfile = f'D://{picname}'
resp = requests.get(url)
b = resp.content
with open(picfile,'wb') as f:
f.write(b)
用来下载文件也是可以的,但数据形式是 html,并不是 markdown。
注意 open() 的参数是 wb,其中 w for writing,b for bytes.
import requests
url = "https://github.com/rumsystem/quorum/blob/main/API.md"
name = url.split("/")[-1]
file = f'D://{name}'
resp = requests.get(url)
b = resp.content
with open(file,'wb') as f:
f.write(b)
返回数据转换为 json 类型
resp.json() 方法和 json.loads(resp.text) 效果相同。
import requests
resp = requests.get("http://httpbin.org/get")
resp.json()
url 的返回值符合 json 语法格式才可以。否则会抛出错误。
比如:
import requests
resp = requests.get("http://baidu.com")
resp.json()
总是可以用 resp.content、resp.text 这两个属性来查看返回值。
resp.text[:100]
带参数的请求
1、直接将参数放在 url 内
import requests
resp = requests.get("http://httpbin.org/get?name=gemey&age=22")
resp.json()
2、把参数填写在 dict 格式的数据 data 中,发起请求时赋值给 params 参数
import requests
data = {
'name': 'tom',
'age': 20
}
resp = requests.get('http://httpbin.org/get', params=data)
resp.json()
3、为 post 请求添加参数
import requests
data = {"name":"tom","age":6}
requests.post('http://httpbin.org/post', data=data)
为请求添加头信息
import requests
headers = {'User-Agent':
'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50'}
requests.get('http://www.baidu.com',headers=headers)
也可以对 headers 进行 update。
import requests
session = requests.Session()
session.verify = r"C:\Users\75801\AppData\Local\Programs\prs-atm-app\resources\quorum_bin\certs\server.crt"
session.headers.update({
"USER-AGENT": "asiagirls-py-bot",
"Content-Type": "application/json",
})
url = "https://127.0.0.1:55043/api/v1/groups"
session.get(url)
会话维持
import requests
session = requests.Session()
session.verify = r"C:\Users\75801\AppData\Local\Programs\prs-atm-app\resources\quorum_bin\certs\server.crt"
session.headers.update({
"USER-AGENT": "asiagirls-py-bot",
"Content-Type": "application/json",
})
session.get("https://127.0.0.1:55043/api/v1/groups")
session
import requests
session = requests.Session()
session.verify = r".\quorum_bin\certs\server.crt"
session.headers.update({
"USER-AGENT": "asiagirls-py-bot",
"Content-Type": "application/json",
"Connection": "close"
})
session.get("https://127.0.0.1:55043/api/v1/groups")
session
session.get("https://127.0.0.1:55043/api/v1/network")
session
使用代理
同添加headers方法,代理参数也要是一个dict
这里使用requests库爬取了IP代理网站的IP与端口和类型
因为是免费的,使用的代理地址很快就失效了。
我没用过这个功能。这段笔记来自网上检索。
import requests
import re
def get_html(url):
proxy = {
'http': '120.25.253.234:812',
'https': '163.125.222.244:8123'
}
heads = {}
heads['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'
req = requests.get(url, headers=heads,proxies=proxy)
html = req.text
return html
def get_ipport(html):
regex = r'<td data-title="IP">(.+)</td>'
iplist = re.findall(regex, html)
regex2 = '<td data-title="PORT">(.+)</td>'
portlist = re.findall(regex2, html)
regex3 = r'<td data-title="类型">(.+)</td>'
typelist = re.findall(regex3, html)
sumray = []
for i in iplist:
for p in portlist:
for t in typelist:
pass
pass
a = t+','+i + ':' + p
sumray.append(a)
print('高匿代理')
print(sumray)
if __name__ == '__main__':
url = 'http://www.kuaidaili.com/free/'
get_ipport(get_html(url))
证书验证设置
verify 与 ca 认证相关。某些网站不需要,某些网站需要;如果你不提供,会遇到报错。但可以采用如下方式忽略报错:
import requests
from requests.packages import urllib3
urllib3.disable_warnings() #从urllib3中消除警告
resp = requests.get('https://www.12306.cn',verify=False) #证书验证设为FALSE
resp.status_code
但这个作为示例不太好,verify无论是 True 或 False 或 "" 返回码都是 200。
import requests
from requests.packages import urllib3
urllib3.disable_warnings() #从urllib3中消除警告
resp = requests.get('https://www.12306.cn',verify=True)
resp.status_code
import requests
from requests.packages import urllib3
urllib3.disable_warnings() #从urllib3中消除警告
resp = requests.get('https://www.12306.cn',verify="")
resp.status_code
所以我用 Rum 的 API 试试看,它对 verify 是有要求的。
requests.get('https://127.0.0.1:55043/api/v1/groups',verify=True)
requests.get('https://127.0.0.1:55043/api/v1/groups',verify="")
#对verify设置 False,能拿到返回值
requests.get('https://127.0.0.1:55043/api/v1/groups',verify=False)
v = r"C:\Users\75801\AppData\Local\Programs\prs-atm-app\resources\quorum_bin\certs\server.crt"
requests.get('https://127.0.0.1:55043/api/v1/groups',verify=v)
只是有点奇怪,verify 只要不是 True 都能正常返回。
异常捕获
如果用于长时间运行,需要捕获异常并针对性处理。比如有:
import requests
from requests.exceptions import ReadTimeout,HTTPError,RequestException
try:
response = requests.get('http://www.baidu.com',timeout=0.5)
print(response.status_code)
except ReadTimeout:
print('timeout')
except HTTPError:
print('httperror')
except RequestException:
print('reqerror')
这篇笔记是从 Jupyter NoteBook 的 ipynb 文件转换而来,如果想直接运行 .ipynb 文件,可以在我的 github 仓库找到它:
以上就是关于 requests 库的常见用法。