python requests用法总结

本文全部来源于官方文档 http://docs.python-requests.org/en/master/

1、安装

Requests 是一个第三方 Python 模块,其官网的介绍如下:
Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。
警告:非专业使用其他 HTTP 库会导致危险的副作用,包括:安全缺陷症、冗余代码症、重新发明轮子症、啃文档症、抑郁、头疼、甚至死亡。

requests是一个很实用的Python HTTP客户端库,编写爬虫和测试服务器响应数据时经常会用到。可以说,Requests 完全满足如今网络的需求

第三方模块并不是默认的模块,意味着你需要安装它,我们使用 pip3 安装它。

首先要安装 pip3:
$ sudo apt-get update
$ sudo apt-get install python3-pip

安装方式一般采用$ pip install requests。
如果在终端中需要使用代理:pip --proxy http://代理ip:端口 install requests

方法2:通过源码安装

先通过 git 克隆源码库:
git clone git://github.com/kennethreitz/requests.git

或者直接到 github 网页上下载源码压缩包
接着进入到 requests 目录中执行以下命令:
python setup.py install

2、获取响应状态

 

>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code
200
>>> r.headers['content-type']
'application/json; charset=utf8'
>>> r.encoding
'utf-8'
>>> r.text
u'{"type":"User"...'
>>> r.json()
{u'private_gists': 419, u'total_private_repos': 77, ...}

3、获取响应时间

获取elapsed不同的返回值
import requests
r = requests.get("https://baidu.com")
print(r.elapsed)
print(r.elapsed.total_seconds())
print(r.elapsed.microseconds)
print(r.elapsed.seconds)
print(r.elapsed.days)
print(r.elapsed.max)
print(r.elapsed.min)
print(r.elapsed.resolution)

elapsed里面几个方法介绍

  • total_seconds 总时长,单位秒
  • days 以天为单位
  • microseconds (>= 0 and less than 1 second) 获取微秒部分,大于0小于1秒
  • seconds Number of seconds (>= 0 and less than 1 day) 秒,大于0小于1天
  • max = datetime.timedelta(999999999, 86399, 999999) 最大时间
  • min = datetime.timedelta(-999999999) 最小时间
  • resolution = datetime.timedelta(0, 0, 1) 最小时间单位

4、timeout超时

1.如果一个请求响应时间比较长,不能一直等着,可以设置一个超时时间,让它抛出异常
2.如下请求,设置超时为1s,那么就会抛出这个异常:requests.exceptions.ConnectTimeout: HTTPConnectionPool

import requests
r = requests.get("http://cn.python-requests.org/zh_CN/latest/", timeout=1)
print(r.elapsed)
print(r.elapsed.total_seconds())
print(r.elapsed.microseconds)

5、例子

import requests

def url_req_test(url):
    def inner():
        r = requests.get(url)
        print('访问状态:%s,响应时间:%s秒' %(r.status_code, r.elapsed.total_seconds()))
    return inner

baidu = url_req_test('https://www.baidu.com')
qq = url_req_test('https://www.qq.com')

baidu()
qq()
访问状态:200,响应时间:0.807591秒
访问状态:200,响应时间:0.108424秒

post请求

request以params参数格式传递

API_KEY = 'x]~xvJ?_*}A<uruGobvo^!c)Tt6ZFi35'
ctime = time.time()

def gen_key(ctime):
    string = '{}{}'.format(API_KEY,ctime)
    md5 = hashlib.md5()
    md5.update(string.encode('utf-8'))
    ret = md5.hexdigest()
    return ret

def send_alert(ctime):
    url = 'http://127.0.0.1:5000/api/test'
    data = {
        'username': 'test',
        'password': '123'
    }
    params={'key':gen_key(ctime),'ctime':ctime}    
    r = requests.post(url, data=data, params=params)
    print(r.text)

服务端接收request.POST的url会显示如下:
"POST /api/v1/ticket/jumper_add/?key=fd627c3d91a725c9c67789e1eefd6f66&ctime=1619677176.8553472 HTTP/1.1" 200 34

可以看到参数被放到了url参数中,可以通过request.GET获取
sign = request.GET.get('key')
ctime = request.GET.get('ctime')

request以form格式传递

def send_alert():
    url = 'http://127.0.0.1:5000/api/test'
    data = {
        'username': 'test',
        'password': '123'
    }

    r = requests.post(url, data=data)
    print(r.text)

send_alert()

request以json格式传递

import requests

def send_alert():
    url = 'http://127.0.0.1:5000/api/test'
    data = {
        'username': 'test',
        'password': '123'
    }

    r = requests.post(url, json=data)
    #或者将data序列化
    #r = requests.post(url, data=json.dumps(data))
    print(r.text)

send_alert()

 

delete请求

例子:

api_url = "https://www.example.com/api/v1"

signature_headers = ['(request-target)', 'accept', 'date']

headers = {
    'Accept': 'application/json',
    'Date': time.strftime('%x %X')
}

auth = HTTPSignatureAuth(key_id=KEY_ID, secret=SECRET,
                         algorithm='hmac-sha256',
                         headers=signature_headers)

def request_del(url, data):
    url = '%s/perms/asset-permissions-assets-relations/' % api_url
    data = {
        "assetpermission": asset_permission_id,
        "asset": asset_id,
    }
    req = requests.delete(url, auth=auth, headers=headers, json=data, verify=False)
    if req.status_code == 204:
        return req.json()
    else:
        print(req.status_code)
        print(req.text)
        return False

问题1:

HTTPS请求进行SSL验证或忽略SSL验证才能请求成功,忽略方式为verify=False

url = 'https://xxx.com'
r = requests.get(url,verify=False) 

问题2:

向服务器发布post请求时报错Forbidden (CSRF cookie not set.)
在服务端添加csrf_exempt装饰器

from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse

@csrf_exempt
def postback(request):
print(request.POST)
return JsonResponse({'ok': 'hoooh!'})

 问题3:

InsecureRequestWarning: Unverified HTTPS request is being made to host 'user-cec.cec.com.cn'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecureRequestWarning,

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

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

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

解决办法:
添加两行代码,禁用urllib3,将不再提示警告信息

import urllib3
urllib3.disable_warnings()

 

posted on 2019-01-01 11:09  longfei2021  阅读(210)  评论(0编辑  收藏  举报