python中的Web 请求库包括requests 、urllib、http.client。requests 是 Python 最流行、最人性化的 HTTP 客户端库,被称为“让 HTTP 请求变得优雅的库”。相比标准库 urllibhttp.client,它极大简化了发起请求、处理响应的复杂度,语法直观,功能强大。Requests是基于urllib,使用**Apache2 Licensed许可证开发的HTTP**库。其在python内置模块的基础上进行了高度封装,使得Requests能够轻松完成浏览器相关的任何操作。Requests能够模拟浏览器的请求,比起上一代的urllib库,Requests实现爬虫更加便捷迅速。下面主要介绍request库。

一、request的请求方式

request的请求包含三个基础参数,分别是method、url、**kwargs。request(method, url, **kwargs)

二、request的请求模式-mothod

​ method有七种方法,GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS。可以用requests.request在参数中带上mothod,也可以用封装好的requests.get()的方式。
从源码查看不同模式的入参:
get(url, params=None, **kwargs)
post(url, data=None, json=None, **kwargs)
delete(url, **kwargs)
put(url, data=None, **kwargs)
patch(url, data=None, **kwargs)
options(url, **kwargs)
head(url, **kwargs)

三、request的请求参数-kwargs

**kwargs控制访问参数共13种。一般请求下不同的请求参数不太相同,下面介绍常用几种

  • params: 字典或字节序列,作为参数增加到url中;
  • data: 字典、字节序列或文件对象,作为Request的内容;
  • json: JSON格式的数据,作为Request的内容;
  • headers: 字典,HTTP定制头;
  • cookies: 字典或CookieJar,Request中的cookie;
  • auth: 元组,支持HTTP认证功能;
  • files: 字典类型,传输文件;
  • timeout: 设定超时时间,秒为单位;
  • proxies: 字典类型,设定访问代理服务器,可以增加登录认证;
  • allow_redirects: True/False,默认为True,重定向开关;
  • stream : True/False,默认为True,获取内容立即下载开关;
  • verify: True/False,默认为True,认证SSL证书开关;
  • cert: 本地SSL证书路径。

3.1、params

一般get请求才会带上params,参数会增加到url中,作为url的一部分

import requests

params = {'key1': 'value1', 'key2': 'value2'}
r = requests.request('GET', 'http://python123.io/ws', params=params)
print(r.url)

https://python123.io/ws?key1=value1&key2=value2

3.1、data

​ data一般为post、put、delete等才会带上的参数,可以传入text、json、xml等数据。但是传入json的时候需要指定header,所以一般json数据用json传入。

​ 在Python的Requests库中,data和json参数都是来定义 HTTP 请求的 Body(请求体)内容 的。它们的主要区别在于数据的编码方式和Content-Type头部。data参数通常用于发送表单数据,其数据会被编码为application/x-www-form-urlencoded格式,而json参数用于发送JSON格式的数据,其数据会被编码为application/json格式。通常他们都是互斥的,根据后端实现的不同选择合适的参数

import requests

mx = {'key1': 'value1', 'key2': 'value2'}
r1 = requests.request('POST', 'http://python123.io/ws', data=mx)
body = 'aha'
r2 = requests.request('POST', 'http://python123.io/ws', data=body)

print(r1.request.body,r1.request.header)
print(r2.request.body,r2.request.header)

key1=value1&key2=value2 {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '23', 'Content-Type': 'application/x-www-form-urlencoded'}
aha {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '3'}

3.2、json

import requests

mx = {'key1': 'value1', 'key2': 'value2'}
r1 = requests.request('POST', 'http://python123.io/ws',json=mx)

print(r1.request.body)

'{"key1": "value1", "key2": "value2"}' {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '36', 'Content-Type': 'application/json'}

3.3、file

import requests

mx = {'key1': 'value1', 'key2': 'value2'}
file= open("test.txt","rb+")
r1 = requests.request('POST', 'http://python123.io/ws',files={"file":file})

print(r1.request.body)

b'--1fbbcf0f727a846963e8685c8f232b8d\r\nContent-Disposition: form-data; name="file"; filename="test.txt"\r\n\r\naa\r\n--1fbbcf0f727a846963e8685c8f232b8d--\r\n' {'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '146', 'Content-Type': 'multipart/form-data; boundary=1fbbcf0f727a846963e8685c8f232b8d'}

3.4、header

一般请求时request会根据请求参数的不同,自动带上header。用户也可以自己手动带上header,但是需要注意header的类型需要和传入的参数一致,否则请求会报错

3.5、auth

有些接口带了认证信息,需要在auth中传入

import requests

mx = {'key1': 'value1', 'key2': 'value2'}
r1 = requests.request('POST', 'http://python123.io/ws',data=mx,auth=("admin","123123"))

print(r1.request.headers)

{'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '23', 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic YWRtaW46MTIzMTIz'}

3.6、verify

verify 参数用于控制是否验证 SSL 证书,默认值为True。一般情况下在网页请求时是需要校验的,verify=False会禁用 SSL 证书验证。这意味着即使服务器的 SSL 证书无效、自签名或与域名不匹配,请求仍会成功发送。注意:这样做会有安全风险,容易受到中间人攻击(Man-In-The-Middle Attack),不建议在生产环境中使用。

res=requests.get(url,verify=False)

verify=False 访问一个网站https的网站时会出现如下报错,可以使用urllib3.disable_warnings()屏蔽报错

D:\python3\Lib\site-packages\urllib3\connectionpool.py:1099: InsecureRequestWarning: Unverified HTTPS request is being made to host 'www.baidu.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
import requests
import urllib3

urllib3.disable_warnings()

url = "https://www.baidu.com"

res = requests.get(url, auth=("admin", "NoahPingtai2021!@#"), verify=False)
print(res.text)

四、request的返回内容-response

Response对象包含服务器返回的所有信息,同时也包含了我们向服务器发送请求的Request信息,返回的response常用对象属性如下:

print(r.status_code): 响应状态码,返回值为200表示网络请求正常,3xx表示重定向,4xx表示客户端错误–401认证,5xx表示服务端错误。
print(r.request): 请求对象,主要包括:r.request.url, r.request.method, r.request.headers,r.request.body
print(r.url): 请求的url
print(r.text):输出网页源代码,返回的数据类型为字符串类型。
print(r.content): 输出网页源代码,返回的数据类型为bytes类型
print(ret.headers): 响应的头部信息
print(ret.cookies): 服务器返回的Cookies信息
print(ret.ok):如果响应状态码为200到299之间,返回True
print(r.encoding):返回内容的编码

1. Response.content:原始字节流

content返回的是未经解码的原始二进制数据数据类型为 Python 的bytes(字节串)。它直接对应服务器发送的 HTTP 响应体的 “原始字节”,不做任何编码转换 —— 相当于把服务器返回的 “01 二进制流” 直接包装成bytes对象,保留数据最原始的形态。

例如,当请求一张图片、一个 PDF 文件或一段视频时,服务器返回的本质是 “二进制文件流”,content会完整保留这些二进制数据,不进行任何修改。

2. Response.text:解码后的字符串

text返回的是经过编码转换后的字符串数据类型为 Python 的str(字符串)。它的本质是对content(原始字节流)进行 “解码” 处理后的结果 ——requests会先推测服务器返回数据的编码格式(如 UTF-8、GBK、ISO-8859-1 等),再用该编码将bytes类型的content转换为人类可阅读的str类型。

3. Response.json():解码后的字符串

response.json()将响应内容解析为JSON格式,并返回对应的Python数据结构。通过type()函数可以查看json变量的数据类型。打印json变量将显示解析后的字典或列表对象。

注意:只有当响应内容的MIME类型为application/json时,response.json()才会成功解析JSON数据。

import requests

param={"is_filter":"1"}
mx = {"id":"12306","name":"moco"}
ret = requests.request('POST', 'http://10.58.83.36:8889/license/perf-auth-num/data_source',params=param,json=mx)

#返回状态码,
print(ret.status_code)
200

print(ret.url)
print(ret.request.url)
http://10.58.83.36:8889/license/perf-auth-num/data_source?is_filter=1
http://10.58.83.36:8889/license/perf-auth-num/data_source?is_filter=1

print(ret.headers)
{'Content-Length': '80', 'Content-Type': 'application/json; charset=utf-8'}

print(ret.request.headers)
print(ret.request.method)
print(ret.request.body)
{'User-Agent': 'python-requests/2.32.3', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '31', 'Content-Type': 'application/json'}
POST
b'{"id": "12306", "name": "moco"}'

print(ret.json(),type(ret.json()))
print(ret.text,type(ret.text))
print(ret.content)
{'data': {'data_source': 36}, 'errCode': 200, 'errMsg': '', 'requestId': 0, 'service': ''} <class 'dict'>
{"data":{"data_source":36},"errCode":200,"errMsg":"","requestId":0,"service":""} <class 'str'>
b'{"data":{"data_source":36},"errCode":200,"errMsg":"","requestId":0,"service":""}' <class 'bytes'>

print(ret.cookies)
print(ret.encoding)
<RequestsCookieJar[]>
utf-8

print(ret.elapsed)
print(ret.history)
print(ret.ok)
0:00:00.148948
[]
True

六、自动化request的封装

import requests
import urllib3
from common.config import *
from common.logger_utils import log

urllib3.disable_warnings()


class HttpRequests:

    def __init__(self):
        super().__init__()
        self.config_url = conf_url
        self.user = username
        self.password = password
        self.auth = (username, password)
        self.headers = {"appid": appid, "appsecret": appsecret}

    def login(self):
        result = requests.post(url=self.config_url+'/api/v1/login/loginByPassword',
                               json={'login': self.user, 'password': self.password}, verify=False)
        return {'Cookie': result.headers['Set-Cookie'], 'csrftoken': result.json()['csrfToken']}

    def get_request(self, url, **kwargs):
        try:
            result = requests.get(url=self.config_url+url, auth=self.auth, headers=self.headers, **kwargs, verify=False, timeout=300)
            log.info("request data: {}".format(kwargs))
            log.info(result.url)
        except Exception as err:
            result = ''
            log.debug('GET请求出错-->%s,出错原因:%s' % (url, err))
        return result

    def post_request(self, url, **kwargs):
        try:
            result = requests.post(url=self.config_url+url, auth=self.auth, headers=self.headers, **kwargs, verify=False, timeout=300)
            log.info("request data: {}".format(kwargs))
            log.info(result.url)
        except Exception as err:
            result = ''
            log.debug('POST请求出错-->%s,出错原因:%s' % (url, err))
        return result

    def put_request(self, url, data=None, **kwargs):
        try:
            result = requests.put(url=self.config_url+url, auth=self.auth, data=data, headers=self.headers, **kwargs, verify=False, timeout=300)
            log.info("request data: {}".format(kwargs))
            log.info(result.url)
        except Exception as err:
            result = ''
            log.debug('PUT请求出错-->%s,出错原因:%s' % (url, err))
        return result

    def delete_request(self, url, **kwargs):
        try:
            result = requests.delete(url=self.config_url+url, auth=self.auth, headers=self.headers, **kwargs, verify=False, timeout=300)
            log.info("request data: {}".format(kwargs))
            log.info(result.url)
        except Exception as err:
            result = ''
            log.debug('DELETE请求出错-->%s,出错原因:%s' % (url, err))
        return result

    def patch_request(self, url, data=None, **kwargs):
        try:
            result = requests.patch(url=self.config_url+url, auth=self.auth, data=data, headers=self.headers, **kwargs, verify=False, timeout=300)
            log.info("request data: {}".format(kwargs))
            log.info(result.url)
        except Exception as err:
            result = ''
            log.debug('PATCH请求出错-->%s,出错原因:%s' % (url, err))
        return result
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐