requests库介绍和安装

urllib库是python自带的一个库,requests库是第三方的库,需要安装

urllib库用起来很麻烦,比较繁琐

requests库是基于urllib库采用Apache2协议开源的Python HTTP库,号称是为人类准备的HTTP库

下载安装

1
pip3 install  requests

可以在调用的使用有点可能需要root权限才行

requests请求的方法

requests支持很多种的请求方法,下面的八种请求方法

方法 解释
requests.request() 构造一个请求,支持以下各种方法
requests.get() 获取html的主要方法
requests.head() 获取html头部信息的主要方法
requests.post() 向html网页提交post请求的方法
requests.put() 向html网页提交put请求的方法
requests.patch() 向html提交局部修改的请求
requests.delete() 向html提交删除请求

这个网站可以验证请求http://httpbin.org/会吧你请求的数据给返回回来

下面演示一下GET请求

image-20210227123353674

打开GET

image-20210227123537676

image-20210227123614207

他会给你一个URL

image-20210311105256820

我们访问他看一下

他会叫请求的内容给返回回来

image-20210227123716769

Response响应属性

下面我常用的

属性 作用
r.text 响应回字符串数据,比如网站源代码
r.status_code 响应的状态码
r.content 二进制响应回去的内容,比如照片视频
r.url 获取请求地址
r.cookies 获取请求后的cookies信息
r.cookies.get_dict() 获取返回的cookies信息
r.request 获取请求方式
r.encoding 进行Response对象编码,就是编码
r.json() 内置的json解码器
r.headers 叫请求的全部的头部变成字典,字典键不区分大小写
r.history 属性得到请求历史

GET请求

HTTP 中最常见的请求之一就是 GET 请求

基本实例

代码

1
2
3
4
import requests

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

结果

1
2
3
4
5
6
7
8
9
10
11
12
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.25.1",
"X-Amzn-Trace-Id": "Root=1-6039d18d-5cb9a49d6c15706c15d339e3"
},
"origin": "39.149.143.81",
"url": "http://httpbin.org/get"
}

image-20210227125934173

get()方法的参数

格式

1
requests.get('url',参数,修改头)

下面是演示

get请求参数

直接添加参数是不灵活的例如

1
2
3
4
5
import requests

r = requests.get('http://httpbin.org/get?name=germey&age=22')

print(r.text)

我们可以用字典的方式进行参数添加

1
2
3
4
5
6
7
8
9
10
11
import requests

# 参数,用字典的键值对来定义
data = {
'name': 'germey',
'age': 22
}
# 添加上面的定义的字典
r = requests.get("http://httpbin.org/get", params=data)
# 输出源代码
print(r.text)

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"args": {
"age": "22",
"name": "germey"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.23.0",
"X-Amzn-Trace-Id": "Root=1-603a00e4-1baf3cb401034c75137d2812"
},
"origin": "39.149.143.81",
"url": "http://httpbin.org/get?age=22&name=germey"
}

image-20210227162130894

修改get请求头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests  

data = { # 参数 用字典的键值对来定义
'name': 'germey',
'age': 22
}


headers = { # 定义User-Agent请求头,用键值对的方式
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"
}

# 添加上面的定义的字典
r = requests.get("http://httpbin.org/get", params=data ,headers=headers)

# 输出源代码
print(r.text)

POST 请求

POST请求很简单

1
2
3
4
5
6
7
8
import requests

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

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"args": {},
"data": "",
"files": {},
"form": {
"age": "22",
"name": "germey"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "18",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.23.0",
"X-Amzn-Trace-Id": "Root=1-603a179f-426a621011f59bda70eb583d"
},
"json": null,
"origin": "39.149.143.81",
"url": "http://httpbin.org/post"
}

请求的数据包

image-20210817123219791

JSON解码

下面的就是用的AJAX实现的

2021-02-2716-43-14

JSON和XML差不多用来保存数据的

下面这个就是JSON数据

image-20210227170319476

JSON–就是键值对

地址是https://image.baidu.com/search/acjson?tn=resultjson_com&logid=6350051297420797401&ipn=rj&ct=201326592&is=&fp=result&queryWord=a&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=&z=&ic=&hd=&latest=&copyright=&word=a&s=&se=&tab=&width=&height=&face=&istype=&qc=&nc=1&fr=&expermode=&force=&pn=30&rn=30&gsm=1e&1614416309835=

image-20210227170354540

我们就可以用响应属性json()属性来解析他

1
2
3
4
5
6
import requests  

# https://api.github.com/events是json地址
r = requests.get('https://api.github.com/events')
# 解析json并输出出来
print(r.json())

结果

1
[{u'repository': {u'open_issues': 0, u'url': '......太多了

抓取二进制数据

抓取二进制的的比如图片、音频、视频等文件,我们就可以用响应属性content属性

下面就抓取这个照片我的头像嘻嘻地址https://zssnp-1301606049.cos.ap-nanjing.myqcloud.com/img/avatar.png

image-20210227173458314

我们先看一下输出的二进制

1
2
3
4
5
import requests

r = requests.get("https://zssnp-1301606049.cos.ap-nanjing.myqcloud.com/img/avatar.png")

print(r.content)

结果什么也看不懂

1
H-�@��9��[��]K��/H�H��Tԃ7/�/����.�5�؊�X��EMES��^�O���q�TQՓ      �8�Lٙ�Y#�JБ�L՚�ٞ�ٟڠ=��;

我们可以叫他直接保存上图像,要是保存文件是二进制要wb这样写入文件必然不行

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

# 请求我的头像图片
r = requests.get("https://zssnp-1301606049.cos.ap-nanjing.myqcloud.com/img/avatar.png")

# 写入文件的方式打开
a=open('a.png',"wb")

# 向a.png文件里面写入请求的返回二进制的内容
a.write(r.content)

# 关闭文件
a.close()

结果可以看见没有问题,也可以获取音频和视频文件

image-20210227174629310

响应头判断

状态码常用来判断请求是否成功,而 requests 还提供了一个内置的状态码查询对象requests.codes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 信息性状态码
100: ('continue',),
101: ('switching_protocols',),
102: ('processing',),
103: ('checkpoint',),
122: ('uri_too_long', 'request_uri_too_long'),

# 成功状态码
200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'),
201: ('created',),
202: ('accepted',),
203: ('non_authoritative_info', 'non_authoritative_information'),
204: ('no_content',),
205: ('reset_content', 'reset'),
206: ('partial_content', 'partial'),
207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'),
208: ('already_reported',),
226: ('im_used',),

# 重定向状态码
300: ('multiple_choices',),
301: ('moved_permanently', 'moved', '\\o-'),
302: ('found',),
303: ('see_other', 'other'),
304: ('not_modified',),
305: ('use_proxy',),
306: ('switch_proxy',),
307: ('temporary_redirect', 'temporary_moved', 'temporary'),
308: ('permanent_redirect',
'resume_incomplete', 'resume',), # These 2 to be removed in 3.0

# 客户端错误状态码
400: ('bad_request', 'bad'),
401: ('unauthorized',),
402: ('payment_required', 'payment'),
403: ('forbidden',),
404: ('not_found', '-o-'),
405: ('method_not_allowed', 'not_allowed'),
406: ('not_acceptable',),
407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'),
408: ('request_timeout', 'timeout'),
409: ('conflict',),
410: ('gone',),
411: ('length_required',),
412: ('precondition_failed', 'precondition'),
413: ('request_entity_too_large',),
414: ('request_uri_too_large',),
415: ('unsupported_media_type', 'unsupported_media', 'media_type'),
416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'),
417: ('expectation_failed',),
418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'),
421: ('misdirected_request',),
422: ('unprocessable_entity', 'unprocessable'),
423: ('locked',),
424: ('failed_dependency', 'dependency'),
425: ('unordered_collection', 'unordered'),
426: ('upgrade_required', 'upgrade'),
428: ('precondition_required', 'precondition'),
429: ('too_many_requests', 'too_many'),
431: ('header_fields_too_large', 'fields_too_large'),
444: ('no_response', 'none'),
449: ('retry_with', 'retry'),
450: ('blocked_by_windows_parental_controls', 'parental_controls'),
451: ('unavailable_for_legal_reasons', 'legal_reasons'),
499: ('client_closed_request',),

# 服务端错误状态码
500: ('internal_server_error', 'server_error', '/o\\', '✗'),
501: ('not_implemented',),
502: ('bad_gateway',),
503: ('service_unavailable', 'unavailable'),
504: ('gateway_timeout',),
505: ('http_version_not_supported', 'http_version'),
506: ('variant_also_negotiates',),
507: ('insufficient_storage',),
509: ('bandwidth_limit_exceeded', 'bandwidth'),
510: ('not_extended',),
511: ('network_authentication_required', 'network_auth', 'network_authentication')

我就演示一下

image-20210227181325655

我们就可以利用这个对象进行判断网站是否请求成功

代码

1
2
3
4
5
6
7
8
9
10
import requests

# 请求百度
r = requests.get('http://www.baidu.com')

# status_code属性显示请求返回的状态码,requests.codes.ok是200状态码
if (r.status_code) == (requests.codes.ok):# 进行比较
print("请求成功")
else:
print("请求错误")

结果

1
请求成功

image-20210227182700730

文件上传

这个环境我用的是upload-labs-master靶场

Cookies

下面我测试的都是DVWA的靶场测试的,看一下他的Cookies

image-20210304101706596

我们简单看一下他的类型

1
2
3
4
>>> import requests
>>> r = requests.get("http://192.168.31.122:8888/login.php")
>>> print(r.cookies)
<RequestsCookieJar[<Cookie PHPSESSID=sfolaoe246rpommhebuttunc37 for 192.168.31.122/>, <Cookie security=low for 192.168.31.122/>]>

他是一个RequestCookieJar 类型的数据

我们可以用items()方法将其转化为元组组成的列表

代码

1
2
3
4
5
6
7
8
#-*- coding: UTF-8 -*- 
import requests

r = requests.get("http://192.168.31.122:8888/login.php")

print(r.cookies)
# 用items()方法将其转化为元组组成的列表
print(r.cookies.items())

结果

1
2
<RequestsCookieJar[<Cookie PHPSESSID=cakg0rbnm1tpoeqoup5ihcmcg4 for 192.168.31.122/>, <Cookie security=low for 192.168.31.122/>]>
[('PHPSESSID', 'cakg0rbnm1tpoeqoup5ihcmcg4'), ('security', 'low')]

图示

image-20210304102253008

上面这个理解可能有点难看一下下面的照片就知道了

可以看见他俩是一样的

image-20210304102500442

用Cookies进行登录

下面这个DVWA登录进入我直接就Cookies给复制出来

image-20210304103208127

内容是PHPSESSID=6sthdjb3suu0obt57lds55ah95; security=low

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
#-*- coding: UTF-8 -*- 
import requests


headers = { # 叫Cookie头添加进入
"Cookie": "PHPSESSID=6sthdjb3suu0obt57lds55ah95; security=low",
}

r = requests.get("http://192.168.31.122:8888/index.php",headers=headers)

# 输出响应的源码
print(r.text)

结果

image-20210304104218669

我叫Cookie故意写错看看他就不会登录

可以看见严重失败

image-20210304104332236

构建RequestCookieJar 对象登录

RequestsCookieJar 对象发送请求头,这相对烦琐

书上写的是下面这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-- coding:UTF-8 --
import requests


# 叫cookies给cookies变量
cookies = 'PHPSESSID=6sthdjb3suu0obt57lds55ah95; security=low'

# 新建了一个 RequestCookieJar 对象
jar = requests.cookies.RequestsCookieJar()

# split() 方法分割
for cookie in cookies.split(';'):
# split() 方法分割
key, value = cookie.split('=', 1)
# set() 方法设置好每个 Cookie 的 key 和 value
jar.set(key, value)
print(jar.items())

结果

1
[(' security', 'low'), ('PHPSESSID', '6sthdjb3suu0obt57lds55ah95')]

上面的代码分析主要分析12行往下的

第12行,可以看一下他的分割的结果,split()方法可以在我以前写的博客上有介绍https://www.zssnp.top/2020/05/01/python

1
2
3
4
5
6
7
8
9
10
11
#-- coding:UTF-8 --
import requests
# 叫cookies给cookies变量
cookies = 'PHPSESSID=6sthdjb3suu0obt57lds55ah95; security=low'

# 新建了一个 RequestCookieJar 对象
jar = requests.cookies.RequestsCookieJar()

# split() 方法分割,分割;的,他会变成列表
cookie=cookies.split(';')
print(cookie)

结果可以看见他遇到;就会分割

1
['PHPSESSID=6sthdjb3suu0obt57lds55ah95', ' security=low']

第14行叫分割的二个参数都给key,value

代码分析,应为上面的用了in他只会提取第一个列表,下面我这个就直接用指定列表来演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#-- coding:UTF-8 --
import requests
# 叫cookies给cookies变量
cookies = 'PHPSESSID=6sthdjb3suu0obt57lds55ah95; security=low'

# 新建了一个 RequestCookieJar 对象
jar = requests.cookies.RequestsCookieJar()

# split() 方法分割,分割;的,他会变成列表
cookie=cookies.split(';')

# 应为上面的用了`in`他只会提取第一个列表,下面我这个就直接用指定列表,叫分割的二个参数都给key,value
key, value=cookie[0].split('=',1)

print(cookie)
print(key)
print(value)

结果

1
2
3
['PHPSESSID=6sthdjb3suu0obt57lds55ah95', ' security=low']
PHPSESSID # key变量输出的
6sthdjb3suu0obt57lds55ah95 # value变量输出的

image-20210304182658147

第16行叫key,value变量给了构建RequestCookieJar对象

代码介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#-- coding:UTF-8 --
import requests
# 叫cookies给cookies变量
cookies = 'PHPSESSID=6sthdjb3suu0obt57lds55ah95; security=low'

# 新建了一个 RequestCookieJar 对象
jar = requests.cookies.RequestsCookieJar()

# split() 方法分割,分割;的,他会变成列表
cookie=cookies.split(';')

# 应为上面的用了`in`他只会提取第一个列表,下面我这个就直接用指定列表,叫分割的二个参数都给key,value
key, value=cookie[0].split('=',1)

# 叫key,value变量给了构建`RequestCookieJar`对象
jar.set(key, value)

print(cookie)
print(key)
print(value)
print(jar.items())

结果,应为是他是列表

1
2
3
4
['PHPSESSID=6sthdjb3suu0obt57lds55ah95', ' security=low']
PHPSESSID # key变量输出的
6sthdjb3suu0obt57lds55ah95 # value变量输出的
[('PHPSESSID', '6sthdjb3suu0obt57lds55ah95')] # jar.items()输出

image-20210304183802426

会话维持

如果我们用同二个请求,也就是说相当于你用了两个浏览器打开了不同的页面

我在两次请求时设置一样的 cookies 不就行了这样比较繁琐

我们就可以用Session 对象,就不用担心 cookies的问题了,下面的测试用的环境是DVWA

我直接请求二次查看他的返回结果

1
2
3
4
5
6
7
8
9
10
11
12
#-- coding:UTF-8 --
import requests

# 请求第一次
r = requests.post("http://192.168.31.122:8888/login.php")
# 输出结果
print(r.cookies.items())

# 请求第二次
r = requests.post("http://192.168.31.122:8888/login.php")
# 输出结果
print(r.cookies.items())

结果,可以看见他两都返回cookies都不一样

1
2
[('PHPSESSID', 'qkmn8nij18qn0di5pskt4feoq2'), ('security', 'low')]
[('PHPSESSID', '9q9bf1vopsg250c4n79sm4r7b7'), ('security', 'low')]

image-20210304195318060

Session 对象维持会话

演示

代码

1
2
3
4
5
6
7
8
9
10
11
#-- coding:UTF-8 --
import requests

s = requests.Session()
r = s.post("http://192.168.31.122:8888/login.php")
# 输出结果
print(r.cookies.items())

# 请求第二次
r = s.post("http://192.168.31.122:8888/login.php")
print(r.cookies.items())

结果,应为你已经有了请求cookies头,所以第二次就不返回给你cookies了,他已经维持了会话

1
2
[('PHPSESSID', 'brn2jv2jlik22i9vohlnp6qvp2'), ('security', 'low')]
[]

image-20210304202233606

SSL 证书验证

这个我就不想找没有认证的ca证书的网站了,下面ca都是我复制书上的

requests 还提供了证书验证的功能,可以使用 verify 参数控制是否检查此证书,默认他是True

image-20210305074317807

现在我们用 requests 来测试一下

1
2
3
4
import requests

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

运行结果如下:

1
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",)

这里提示一个错误 SSLError,表示证书验证错误。所以,如果请求一个 HTTPS 站点,但是证书验证错误的页面时,就会报这样的错误,那么如何避免这个错误呢?很简单,把 verify 参数设置为 False 即可

1
2
3
4
import requests

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

结果

1
2
3
/usr/local/lib/python3.6/site-packages/urllib3/connectionpool.py:852: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning)
200

不过我们发现报了一个警告,它建议我们给它指定证书。我们可以通过设置忽略警告的方式来屏蔽这个警告:

1
2
3
4
5
6
import requests
from requests.packages import urllib3

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

或者通过捕获警告到日志的方式忽略警告:

1
2
3
4
5
import logging
import requests
logging.captureWarnings(True)
response = requests.get('https://www.12306.cn', verify=False)
print(response.status_code)

当然,我们也可以指定一个本地证书用作客户端证书,这可以是单个文件(包含密钥和证书)或一个包含两个文件路径的元组:

1
2
3
4
import requests

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

当然,上面的代码是演示实例,我们需要有 crt 和 key 文件,并且指定它们的路径。注意,本地私有证书的 key 必须是解密状态,加密状态的 key 是不支持的

代理设置

我们爬网站的时候可能和被目标网站屏蔽,我们就可以用代理

可以用proxies 参数

HTTP代理

下面用的我用的机场来演示的

image-20210305081421077

演示

1
2
3
4
5
6
7
8
9
10
11
12
13
#-- coding:UTF-8 --
import requests

# 设置代理格式是键值对的方式
proxies = {
"http": "http://192.168.31.122:8889",
"https": "https://192.168.31.122:8889"
}

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

# 输出状态码
print(r.status_code)

结果

1
200

image-20210305080647647

如果带验证的话可以这样写

1
2
3
4
5
6
7
8
9
10
11
#-- coding:UTF-8 --
import requests

# 设置代理格式是键值对的方式
proxies = {
"http": "http://用户名:密码@192.168.31.122:8889",
"https": "https://用户名:密码@192.168.31.122:8889"
}

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

SOCKS代理

安装SOCKS代理命令pip3 install 'requests[socks]'

下面用的我用的机场来演示的

image-20210305081503172

演示

1
2
3
4
5
6
7
8
9
10
11
12
13
#-- coding:UTF-8 --
import requests

# 设置代理格式是键值对的方式
proxies = {
'http': 'socks5://192.168.31.122:1089',
}


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

# 输出状态码
print(r.status_code)

结果

1
200

image-20210305081823179

超时设置

有的时候网页不好我们就可以用这个超时参数来设置超时时间

代码 ,下面我时间我

1
2
3
4
import requests

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

结果

1
requests.exceptions.ConnectTimeout: HTTPSConnectionPool(host='www.baidu.com', port=443): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7f8435c35990>, 'Connection to www.baidu.com timed out. (connect timeout=0.1)'))

我设置3秒就不会报错了

1
2
3
4
import requests

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

结果

1
200

image-20210307153227154

如果想永久等待,可以直接将 timeout 设置为 None,或者什么都不加

1
r = requests.get('https://www.taobao.com', timeout=None)
1
r = requests.get('https://www.taobao.com')

身份认证

下面的内容是我复制的书上的应为我没有这个环境

在访问网站时,我们可能会遇到这样的认证页面,如图 3-9 所示。

img图 3-9 认证页面

此时可以使用 requests 自带的身份认证功能,示例如下:

1
2
3
4
5
import requests
from requests.auth import HTTPBasicAuth

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

如果用户名和密码正确的话,请求时就会自动认证成功,会返回 200 状态码,如果认证失败,则返回 401 状态码。

当然,如果参数都传一个 HTTPBasicAuth 类,就显得有点烦琐了,所以 requests 提供了一个更简单的写法,可以直接传一个元组,它会默认使用 HTTPBasicAuth 这个类来认证。

所以上面的代码可以直接简写如下:

1
2
3
4
import requests

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

此外,requests 还提供了其他认证方式,如 OAuth 认证,不过此时需要安装 oauth 包,安装命令如下:

1
pip3 install requests_oauthlib

使用 OAuth1 认证的方法如下:

1
2
3
4
5
6
7
import requests
from requests_oauthlib import OAuth1

url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET',
'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
requests.get(url, auth=auth)

更多详细的功能可以参考 requests_oauthlib 的官方文档 https://requests-oauthlib.readthedocs.org/,在此不再赘述了

数据结构

数据结构发送,这个数据结构就叫 Prepared Request。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#-- coding:UTF-8 --
from requests import Request, Session

# 定义url地址
url = 'http://httpbin.org/post'

# 定义POST请求内容
data = {
'name': 'germey'
}


# 请求头的内容
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'
}

# 数构造了一个Request对象
req = Request('POST', url, data=data, headers=headers)

# 调用 Session 的 prepare_request() 方法将其转换为一个 Prepared Request 对象
prepped = Session().prepare_request(req)

# 调用 send() 方法发送请求
r = Session().send(prepped)

# 输出返回的内容
print(r.text)

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"args": {},
"data": "",
"files": {},
"form": {
"name": "germey"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "11",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36",
"X-Amzn-Trace-Id": "Root=1-60441e6c-448862e32841f2ea798f9859"
},
"json": null,
"origin": "120.194.193.184",
"url": "http://httpbin.org/post"
}

更多在官方文档里面http://docs.python-requests.org/

实战登录网页

我就登录一下靶场DVWA

我们先查看一下他的POST的参数,我故意密码输入错误

image-20210228154218409

下面这个就是POST的请求参数

image-20210228154340242

内容是username=admin&password=a&Login=Login&user_token=b5ac2d72b51b99c325a33189b8858922