python requests_python模块之requests

我们为什么会害怕?这是由于我们做事不能当机立断,一旦犹豫不决的时候,我们便会畏缩。但如果能够对某件事作明确的判断时,不论有无价值,我们都不会畏缩。

--李小龙
5ec76f852fe0900a6d9071def36dd1c1.png

①requests 是使用Apache2 licensed 许可证的 HTTP 库,用 python编写,比 urllib2 模块更简洁。

② Request 支持 HTTP 连接保持和连接池,支持使用 cookie 保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的 URL和 POST 数据自动编码。

③ 在 python 内置模块的基础上进行了高度的封装,从而使得 python 进行网络请求时,变得人性化(几句代码),使用 Requests可以轻而易举的完成浏览器可有的任何操作。

④ requests 会自动实现持久连接keep-alive。

550a93f6425f2d793c673af7114ea6fb.gif

43b47878dc087b185805a8cb365e57cc.png

5ec76f852fe0900a6d9071def36dd1c1.png1发送请求

前面介绍过 HTTP 的请求方法,GET,POST,HEAD等等,使用 requests 进行网络请求也很简单,导入 requests 模块,然后使用响应的请求方法访问某 URL ,两行代码搞定。

import requestsres = requests.get('http://hunter.com')

这里的 res 就是请求返回的 response 对象,我们可以从该对象中获取响应包的信息,下面会介绍到。其他的请求方法如下:

res = requests.post('http://hunter.com', data={'key': 'value'})res = requests.put('http://hunter.com', data={'key': 'value'})res = requests.delete('http://hunter.com')res = requests.head('http://hunter.com')res = requests.options('http://hunter.com')

四不四很简单0c67de62665c0c5d1b7ccbc1785aa748.png

246e10cbf72be9cd65c2c3ced797108c.png

2传递URL参数

当我们手工地给URL 传递参数的时候,通常情况下是这样:

① GET 传参(参数在 URL)

http://hunter.com/sql-test/getfind-injection.php?username=123&commit=submit

② POST传参(参数在请求包中)

3ba232c073e0bd40ee9d13f277200562.png

使用 requests 模块也可以传参,而且参数是使用字典的 {'key':'value'} 的形式,且 GET 方法使用 params 接收参数,POST 方法使用 data 接收参数。

GET 传参

c19dd60055331b1ea018b5d9f65e4b4a.gif

将参数制成 payload 然后传递给 params。

import requestsurl = "http://hunter.com"payload = {"key1": "value1", "key2": "value2"}r = requests.get(url=url, params=payload)print(r.url)
C:\Users\Lin\Desktop>python3 tmp.pyhttp://hunter.com/?key2=value2&key1=value1

还可以将一个列表作为值传入,由于字典的无序性,所以参数有时候会乱。

import requestsurl = "http://hunter.com"payload = {"key1": "value1", "key2": ["value2", "value3"]}r = requests.get(url=url, params=payload)print(r.url)
C:\Users\Lin\Desktop>python3 tmp.pyhttp://hunter.com/?key2=value2&key2=value3&key1=value1

POST 传参

c19dd60055331b1ea018b5d9f65e4b4a.gif

注意:GET传参使用 params ,POST 传参使用 data 

这里用本地搭建的一个环境做测试,一个简单的表单提交,如果登录成功就显示 login successful

556daaa76e933027db0c11362c3f756f.png

import requestsurl = "http://hunter.com/sql-test/brute.php"payload = {"username": "admin", "password": "admin", "commit": "submit"}r = requests.post(url=url, data=payload)temp = r.content.decode() # 返回响应页面的源码print(res)
C:\Users\Lin\Desktop>python3 tmp.py                brute                        姓名:                密码:                                login successful
3响应对象

使用 Burpsuite 截取的响应包。

bd1db44422807c774188d9125d8a3a24.png

requests 模块的 response 对象可以看到以下的内容,包括但不限于。

功能

方法

响应内容编码(HTTP头的编码)

res.encoding

响应内容编码(内容的编码)

res.apparent_encoding

请求状态码

res.status_code

Text 方法返回的类型

type(res.text)

Content 方法返回的类型

type(res.content)

HTTP 响应内容的头部

res.headers

HTTP 请求内容的头部

res.request.headers

HTTP 响应 cookie

res.cookies

字典的所有键值对

res.hesders.items()

text方法返回网页内容

res.coding="utf-8"

res.text

content方法返回网页内容

res.content.decode()

84f2df14f92a8fb2dd89768048b3b036.png

响应头

84f2df14f92a8fb2dd89768048b3b036.png

查看响应头使用 res.headers,以字典的形式返回。

import requestsurl = 'http://hunter.com'res = requests.get(url=url)print(res.headers)
C:\Users\Lin\Desktop>python3 tmp.py{'Connection': 'Keep-Alive', 'Server': 'Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y PHP/5.2.17', 'Content-Length': '1355', 'Content-Type': 'text/html;charset=UTF-8', 'Date': 'Thu, 16 Jul 2020 09:58:14 GMT', 'Keep-Alive': 'timeout=5, max=100'}

分开字典的键值对,更方便地查看每一个字段。

import requestsurl = 'http://hunter.com'res = requests.get(url=url)for key, value in res.headers.items():    print(key, ':', end="")    print(value)
C:\Users\Lin\Desktop>python3 tmp.pyDate :Thu, 16 Jul 2020 14:00:20 GMTServer :Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y PHP/5.2.17Content-Length :1355Keep-Alive :timeout=5, max=100Connection :Keep-AliveContent-Type :text/html;charset=UTF-8

单看某一个字段的内容

print("服务器使用的服务技术是:", res.headers['server'])
服务器使用的服务技术是:Apache/2.2.25 (Win32) mod_ssl/2.2.25 OpenSSL/0.9.8y PHP/5.2.17
84f2df14f92a8fb2dd89768048b3b036.png

响应内容

84f2df14f92a8fb2dd89768048b3b036.png

requests 模块中使用 response 对象的 text/content 方法获取响应的内容,使用 type 打印 text/content 的类型。

import requestsurl = 'http://hunter.com/sql-test/brute.php'res = requests.get(url=url)res.encoding = "utf-8"result1 = res.textresult2 = res.contentprint(type(result1))print(type(result2))
C:\Users\Lin\Desktop>python3 tmp.py

可以看到 res.text 的类型是 str 而 res.content 的类型是 bytes。

r.textHTTP 响应内容的字符串形式,URL 对应的页面内容
r.contentHTTP 响应内容的二进制形式

两种类型相互转换有如下的关系:

result1 = res.text.encode()result2 = res.content.decode()
C:\Users\Lin\Desktop>python3 tmp.py

但是如果单纯地打印 res.text 会出现下面错误。

C:\Users\Lin\Desktop>python3 tmp.pyTraceback (most recent call last):  File "tmp.py", line 8, in     print(res.text)UnicodeEncodeError: 'gbk' codec can't encode character '\xe5' in position 211: illegal multibyte sequence

简单的说就是响应的内容中有些内容不能被 gbk 编码,解决的方法就是先将 response 响应内容的编码形式指定位 utf-8 然后再打印 res.text。

res.encoding = "utf-8"print(res.text)

显示正常的页面内容。

C:\Users\Lin\Desktop>python3 tmp.py                brute                        姓名:                密码:                                

打印 content 就 decode 一下(默认是以 utf-8 解码为字符串),将 bytes 转换为 str 即可。

print(res.content.decode())
C:\Users\Lin\Desktop>python3 tmp.py                brute                        姓名:                密码:                                

有时候 decode 之后还是出现某些字符不能被 gbk/utf-8 解析,这是后可以使用 ignore 忽略掉,绕过这些不能被解析的字符。

res.content.decode('utf-8','ignore')或者res.content.decode('gbk','ignore')
84f2df14f92a8fb2dd89768048b3b036.png

响应状态码

84f2df14f92a8fb2dd89768048b3b036.png

通过 response 对象的 status_code 返回响应的状态码。

import requestsurl = 'http://hunter.com/sql-test/brute.php'res = requests.get(url=url)print(res.status_code)

200 状态码是最常见的状态,表示服务器已成功处理请求,也说明请求的 URL 存在,在编写目录扫描器中常用此方法判断是否存在此目录。

resquests 模块还附带了一个内置地状态码查询对象,requests.codes.ok。

import requestsurl = "http://hunter.com/upload-labs/Pass-01/index.php"r = requests.get(url)temp = r.status_code == requests.codes.okprint(temp)
C:\Users\Lin\Desktop>python3 tmp.pyTrue

如果发送了一个错误请求(一个 4XX 客户端错误,或者 5XX 服务器错误响应),我们可以通过Response.raise_for_status() 来抛出异常:如果发送了一个正常请求,那么 response.raise_for _status 的值为 None。

import requestsurl = "http://hunter.com/404"r = requests.get(url)print(r.raise_for_status())
C:\Users\Lin\Desktop>python3 tmp.pyTraceback (most recent call last):  File "tmp.py", line 5, in     print(r.raise_for_status())  File "C:\Python35\lib\site-packages\requests\models.py", line 941, in raise_for_status    raise HTTPError(http_error_msg, response=self)requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http://hunter.com/404
4HTTP 代理
import requestsurl = "http://hunter.com"proxise = {"http": "http://127.0.0.1:8080", "https": "https://127.0.0.1:8080"}# verify=False 是设置不验证证书r = requests.get(url=url, proxies=proxise, verify=False)print(r.status_code)

b3871d96ef543afe779e13cc95bd803c.png

requests 库其实是基于 urllib 编写的,对 urllib 进行了封装,使得使用时候的体验好了很多,现在 urllib 已经出到了3版本,功能和性能自然是提升了不少。所以,requests最新版本也是基于最新的 urllib3 进行封装。

urllib2 时代对https的处理非常简单,只需要在请求的时候加上verify=False即可,这个参数的意思是忽略 https 安全证书的验证,也就是不验证证书的可靠性,直接请求,这其实是不安全的,因为证书可以伪造,不验证的话就不能保证数据的真实性。

在urllib3时代,官方强制验证https的安全证书,如果没有通过是不能通过请求的,虽然添加忽略验证的参数,但是依然会给出醒目的 Warning,这一点没毛病。

解决办法:添加两行代码  禁用 urllib3警告

import urllib3urllib3.disable_warnings()
5自定义请求头

有时候,目标经常会检查请求头的某些字段,看看是不是来自正常的客户端(浏览器等)的请求,以此来规避一些爬虫的骚扰,在这里我们就需要自定义请求头了,为了使自己的请求像是浏览器发出的,我们会将程序默认使用的 User-Agent 替换为浏览器的 User-Agent;像某些网站需要 cookie 才能访问的,我们要带上 cookie;如果还要检测 referer 字段的(防止 CSRF/XSS 跨站攻击),我们还要带上合法的 referer 字段。

我们可以通过 response.request.headers 来读取请求头。

import requestsurl = "http://hunter.com"r = requests.get(url)header = r.request.headersfor key, value in header.items():    print(key, ':', end='')    print(value)
C:\Users\Lin\Desktop>python3 tmp.pyConnection :keep-aliveAccept :*/*Accept-Encoding :gzip, deflateUser-Agent :python-requests/2.23.0

自定义请求头也很简单,将内容包装成字典赋值给 headers 即可。

import requestsurl = "http://hunter.com"header = {    'User-Agent': 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',    'cookie': 'this is cookie',    'referer': 'this is referer'}r = requests.get(url=url, headers=header)header = r.request.headersfor key, value in header.items():    print(key, ':', end='')    print(value)
C:\Users\Lin\Desktop>python3 tmp.pyAccept :*/*User-Agent :User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0Accept-Encoding :gzip, deflateConnection :keep-alivereferer :this is referercookie :this is cookie
6更多复杂的POST请求

POST传参除了上面介绍的可以传字典的形式之外,还可以传元组的形式,在表单中多个元素使用同一 key 的时候,这种方式尤其有效:

payload = (('key':'value1'),('key':'value2'))r = request.post(url=url,data=payload)

POST上传文件

注:图片的话推荐使用二进制的形式打开,否则可能会发生错误。

import requestsurl = "http://hunter.com/upload-labs/Pass-01/index.php"file = {"upload_file":open("picture.jpg","rb")} #上传图片r = requests.post(url=url,files=file)r.encoding = 'utf-8'res = r.textprint(res)

你可以显式地设置文件名,文件类型和请求头:

files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}r = requests.post(url, files=files)
7重定向和请求历史

默认情况下,除了 HEAD, Requests 会自动处理所有重定向。

可以使用响应对象的 history 方法来追踪重定向。

Response.history 是一个 Response 对象的列表,为了完成请求而创建了这些对象。这个对象列表按照从最老到最近的请求进行排序。

例如,Github 将所有的 HTTP 请求重定向到 HTTPS:

>>> r = requests.get('http://github.com')>>> r.url'https://github.com/'>>> r.status_code200>>> r.history[301]>]

如果你使用的是GET、OPTIONS、POST、PUT、PATCH 或者 DELETE,那么你可以通过 allow_redirects 参数禁用重定向处理:

>>> r = requests.get('http://github.com', allow_redirects=False)>>> r.status_code301>>> r.history[]

如果你使用了 HEAD,你也可以启用重定向:

>>> r = requests.head('http://github.com', allow_redirects=True)>>> r.url'https://github.com/'>>> r.history[301]>]
8超时

你可以告诉 requests 在经过以 timeout 参数设定的秒数时间之后停止等待响应。基本上所有的生产代码都应该使用这一参数。如果不使用,你的程序可能会永远失去响应:

>>> requests.get('http://github.com', timeout=0.001)Traceback (most recent call last):  File "", line 1, in <module>requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)

注意 timeout 仅对连接过程有效,与响应体的下载无关。timeout 并不是整个下载响应的时间限制,而是如果服务器在 timeout 秒内没有应答,将会引发一个异常(更精确地说,是在 timeout 秒内没有从基础套接字上接收到任何字节的数据时)If no timeout is specified explicitly, requests do not time out.

9错误和异常

遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。

如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError异常。

若请求超时,则抛出一个 Timeout 异常。

若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。

所有 Requests 显示抛出的异常都继承 requests.exceptions.RequestException.

10简易目录扫描器

1.目录扫描原理

①读取字典文件,拼接 URL

② HTTP GET请求URL

③判断状态码,输出存在目录

2.字典文件读取

①方法一:

使用f = open() 打开文件之后要用f.close() 关闭文件

 open(filename,mode) 其中 mode可以是r , w , a

mode

功能

r

只读

w

写操作,并且对之前的内容进行覆盖

a

追加内容

②方法二:

使用withopen("filename.txt","r") as f: 打开文件,在文件读取结束之后会自动关闭文件。

 f.readline()

读取一行

 f.readlines()

读取多行,保存在列表中

 f.read(10)

读取10个字节

3.参数优化

使用sys 模块

C:\>python3homework2.py http://hunter.com/ dir.txt

 sys.argv[0] 对应的时绝对路径下的文件路径如:homework2.py

 sys.argv[1]对应第一个参数如:http://hunter.com

import requestsimport sys#参数优化,用户在控制台输入参数url = sys.argv[1]dic = sys.argv[2]with open("dir.txt","r") as f:  for line in f.readlines():    line = line.strip()    final_url = url + "/" + line    res = requests.get(url=final_url)if res.status_code == 200:print("url:" + res.url + " exist")
C:\Users\Lin\Desktop\>python3 homework2.py http://hunter.com/ dir.txturl:http://hunter.com/sql-php/ existurl:http://hunter.com/xss-php/ exist

最后声明

以上内容主要参考自 requests 初级用法,链接如下:

https://requests.readthedocs.io/zh_CN/latest/user/quickstart.html

7b449e1e2b33c2aef9ec1b58d1fdf22b.png

我是匠心,一个在清流旁默默磨剑的匠人,希望有一天能利刃出鞘,仗剑走江湖。

227a364ebf0584a9474f21fbd748f880.png

好文!点个在看!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值