Requests简介
Requests介绍
Requests是Python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库。相较于urlib更加方便易用。Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。在python内置模块的基础上进行了高度的封装,从而使得python进行网络请求时,变得人性化。
Requests的官方地址为:https://cn.python-requests.org/zh_CN/latest/
Requests安装
$ pip install requests
基础使用
简单例子
测试通过requests
库访问百度首页
import requests
r = requests.get('http://httpbin.org/ip')
print(r)
执行结果:
<Response [200]>
Response对象的常用属性
属性或方法 | 描述 |
---|---|
r.status_code | 响应状态码 |
r.encoding | response对象的编码 |
r.text | 把response对象转换为字符串数据 |
r.content | 把response对象转换成二进制数据 |
r.json() | 通过JSON解码器转换response对象数据 |
r.url | 获取请求网址 |
r.cookie | 获取请求后的cookie |
r.headers | 以字典对象存储服务器响应头 |
演示代码:
import requests
r = requests.get('http://httpbin.org/ip')
print(r)
print(r.status_code)
print(r.encoding)
print(r.content)
print(r.text)
print(r.json())
print(r.headers)
print(r.url)
print(r.cookies)
执行结果:
<Response [200]>
200
utf-8
b'{\n "origin": "24.65.47.34"\n}\n'
{
"origin": "24.65.47.34"
}
{'origin': '24.65.47.34'}
{'Date': 'Tue, 03 Jan 2023 08:17:13 GMT', 'Content-Type': 'application/json', 'Content-Length': '33', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
http://httpbin.org/ip
<RequestsCookieJar[]>
Requests库常用请求方法
方法 | 描述 |
---|---|
requests.session() | 创建一个会话,会话能让在跨请求的时候保持某些参数,比如在同一个session实例发出的所有请求之间保持cookie信息 |
requests.request() | 构造一个请求,支持以下的各种方法 |
requests.get() | 发送一个get请求,获取HTML网页的主要方法,对应HTTP的GET |
requests.post() | 发送一个post请求,向HTML网页提交POST请求的方法,对应HTTP的POST |
requests.head() | 发送一个head请求,获取HTML头信息的方法,对应HTTP的HEAD |
requests.put() | 发送一个put请求,向HTML网页提交PUT请求的方法,对应HTTP的PUT |
requests.patch() | 发送一个patch请求,向HTML网页提交局部修改请求,对应HTTP的PATCH |
requests.delete() | 发送一个delete请求,向HTML网页提交删除请求,对应HTTP的DELETE |
requests.options() | 发送一个options请求,向HTML网页获取服务器支持的HTTP请求方法,对应HTTP的OPTIONS |
其中,requests.get()
、requests.post()
、requests.request()
和requests.session()
最常用
requests.get()
requests的api.py源代码
def get(url, params=None, **kwargs):
r"""Sends a GET request.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request("get", url, params=params, **kwargs)
requests.get()
的基本语法是:
get(url, params=None, **kwargs)
其中:
url
:(必填参数)请求的URL地址;params
:(可选参数)字典或元组列表或字节,作为参数增加到url中;**kwargs
:其他的可选参数,可参考【requests.request()
】中的**kwargs
;
示例网站:https://httpbin.org
示例1:
import requests
r = requests.get('https://httpbin.org/ip')
print(r)
print(r.status_code)
print(r.encoding)
print(r.content)
print(r.text)
print(r.json())
print(r.headers)
print(r.url)
print(r.cookies)
执行结果:
<Response [200]>
200
utf-8
b'{\n "origin": "64.65.47.34"\n}\n'
{
"origin": "64.65.47.34"
}
{'origin': '124.65.147.234'}
{'Date': 'Wed, 04 Jan 2023 07:28:15 GMT', 'Content-Type': 'application/json', 'Content-Length': '33', 'Connection': 'keep-alive', 'Server': 'gunicorn/19.9.0', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true'}
https://httpbin.org/ip
<RequestsCookieJar[]>
示例2:(含有params
参数时)
import requests
r = requests.get('https://httpbin.org/get', params={'name': 'laobai', 'age': 18})
print(r.json())
执行结果:
{'args': {'age': '18', 'name': 'laobai'}, 'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'python-requests/2.28.1', 'X-Amzn-Trace-Id': 'Root=1-63b52b16-0b6f50d7668fa5ab52669f76'}, 'origin': '124.65.147.234', 'url': 'https://httpbin.org/get?name=laobai&age=18'}
requests.post()
requests的api.py源代码
def post(url, data=None, json=None, **kwargs):
r"""Sends a POST request.
:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json data to send in the body of the :class:`Request`.
:param \*\*kwargs: Optional arguments that ``request`` takes.
:return: :class:`Response <Response>` object
:rtype: requests.Response
"""
return request("post", url, data=data, json=json, **kwargs)
requests.post()
的基本语法是:
post(url, data=None, json=None, **kwargs)
其中:
url
:(必填参数)请求的URL地址;data=None
:(可选参数)字典,元组列表,字节或文件对象,作为post请求的参数。(content_type
为application/x-www-form-urlencode
键值对的编码格式);json=None
:(可选参数)JSON格式的数据,作为post请求的json参数。(content_type
为application/json
)(使用json
接收会自动将字典转换为json
;也可以用data
接收json
格式的数据,data=json.dump(字典格式的数据)
);**kwargs
:其他的可选参数,可参考【requests.request()
】中的**kwargs
;
传递参数是用data还是json,需要根据Content-Type的类型来判断
Content-Type是服务器要求传入的报文的内容类型:
- Content-Type:application/json 用json接收
- Content-Type:application-www-form-urlencoded 用data接收
- Content-Type:text/plain 用data接收
示例网站:http://101.43.8.10:6969/(likeshop商城)
示例1:登录接口( http://www.likeshop.cn/doc/2/173 )
import requests
url1 = 'http://101.43.8.10:6969/api/account/login'
data1 = {
'account': '17900000001',
'password': 'a123456',
'client': 2
}
r1 = requests.post(url=url1, data=data1)
print(r1.json())
执行结果:
{'code': 1, 'msg': '登录成功', 'data': {'id': 1, 'nickname': '测试账号一', 'avatar': 'http://101.43.8.10:6969/static/common/image/default/user.png', 'level': 1, 'disable': 0, 'distribution_code': 'TVHYKM', 'token': '7a81e50075f4afb54eef89c6d0c29e8e'}, 'show': 0, 'time': '0.100006'}
从登录接口的执行接口可以看到生成了token
示例2:个人中心接口( http://www.likeshop.cn/doc/2/287 )
import requests
url2 = 'http://101.43.8.10:6969/api/user/center'
r2 = requests.post(url=url2)
print(r2.json())
执行结果:
{'code': -1, 'msg': 'token不能为空', 'data': [], 'show': 1, 'time': '0.042536'}
这里提示缺少token
,需要在发送请求时,在headers
中增加token
参数
import requests
url1 = 'http://101.43.8.10:6969/api/account/login'
data1 = {
'account': '17900000001',
'password': 'a123456',
'client': 2
}
r1 = requests.post(url=url1, data=data1)
url2 = 'http://101.43.8.10:6969/api/user/center'
headers = {
'token': r1.json()['data']['token']
}
r2 = requests.post(url=url2, headers=headers)
print(r2.json())
再次执行:
{'code': 1, 'msg': '获取成功', 'data': {'id': 1, 'sn': '61853905', 'nickname': '测试账号一', 'avatar': 'http://101.43.8.10:6969/static/common/image/default/user.png', 'mobile': '17900000001', 'level': '普通会员', 'user_money': '9960.20', 'user_integral': 1020, 'total_order_amount': '39.80', 'total_recharge_amount': '0.00', 'distribution_code': 'TVHYKM', 'wait_pay': 0, 'wait_delivery': 1, 'wait_take': 0, 'wait_comment': 0, 'after_sale': 0, 'coupon': 0, 'distribution_setting': 1, 'notice_num': 1, 'next_level_tips': '距离升级还差999', 'hasPayPassword': 0}, 'show': 0, 'time': '0.078589'}
requests.request()
requests的api.py源代码
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
:param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary, list of tuples or bytes to send
in the query string for the :class:`Request`.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
:param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
to add for the file.
:param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How many seconds to wait for the server to send data
before giving up, as a float, or a :ref:`(connect timeout, read
timeout) <timeouts>` tuple.
:type timeout: float or tuple
:param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
:param verify: (optional) Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use. Defaults to ``True``.
:param stream: (optional) if ``False``, the response content will be immediately downloaded.
:param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
:return: :class:`Response <Response>` object
:rtype: requests.Response
Usage::
>>> import requests
>>> req = requests.request('GET', 'https://httpbin.org/get')
>>> req
<Response [200]>
"""
# By using the 'with' statement we are sure the session is closed, thus we
# avoid leaving sockets open which can trigger a ResourceWarning in some
# cases, and look like a memory leak in others.
with sessions.Session() as session:
return session.request(method=method, url=url, **kwargs)
requests.request()
的基本语法是:
requests.request(method,url,**kwargs)
其中:
method
:(必填参数)GET
、POST
、HEAD
、PUT
、DELETE
、PATCH
或OPTIONS;
url
:(必填参数)请求的URL地址;**kwargs
:(可选参数)是一个可变的参数类型,在传实参时,以关键字参数的形式传入,python会自动解析成字典的形式;params
:字典或元组列表或字节,作为参数增加到url中;一般用于get请求,post请求也可用(不常用);data
:字典,元组列表,字节或文件对象,作为post请求的参数。(content_type
为application/x-www-form-urlencode
键值对的编码格式);json
:JSON格式的数据,作为post请求的json参数。(content_type
为application/json
)(使用json
接收会自动将字典转换为json
;也可以用data
接收json
格式的数据,data=json.dump(字典格式的数据)
);headers
:字典类型, HTTP请求头信息;cookies
:字典或CookieJar,Request中的auth : 元组支持HTTP认证功能;files
:字典类型,传输文件,作为post请求文件流数据;timeout
:设定超时时间,秒为单位;proxies
:字典类型,设定访问代理服务器,可以增加登录认证;allow_redirects
:True/False,默认为True,重定向开关;stream
:True/False,默认为True,获取内容立即下载开关;verify
:True/False,默认为True,认证SSL证书开关。当verify为True时, 如果想解析https内容,需在Cert参数中添加证书路径;cert
:本地SSL证书的路径;auth
:元组,支持HTTP认证功能(“证书、密钥”对);
requests.request(method,url,params=None,data=None,headers=None,cookies=None,
files=None,auth=None,timeout=None,allow_redirects=True,
proxies=None,hooks=None,stream=None,verify=None,cert=None,json=None)
示例:
import requests
url = 'http://101.43.8.10:6969/api/account/login'
data = {
'account': '17900000001',
'password': 'a123456',
'client': 2
}
res = requests.request('post', url=url, data=data)
print(res.json())
执行结果:
{'code': 1, 'msg': '登录成功', 'data': {'id': 1, 'nickname': '测试账号一', 'avatar': 'http://101.43.8.10:6969/static/common/image/default/user.png', 'level': 1, 'disable': 0, 'distribution_code': 'TVHYKM', 'token': '9dc861b841c7abab6068dd2f6393bd45'}, 'show': 0, 'time': '0.100812'}
requests.session()
requests的sessions.py源代码
def request(self, method, url,
params=None, data=None, headers=None, cookies=None, files=None,
auth=None, timeout=None, allow_redirects=True, proxies=None,
hooks=None, stream=None, verify=None, cert=None, json=None):
"""Constructs a :class:`Request <Request>`, prepares it and sends it.
Returns :class:`Response <Response>` object.
:param method: method for the new :class:`Request` object.
:param url: URL for the new :class:`Request` object.
:param params: (optional) Dictionary or bytes to be sent in the query
string for the :class:`Request`.
:param data: (optional) Dictionary, list of tuples, bytes, or file-like
object to send in the body of the :class:`Request`.
:param json: (optional) json to send in the body of the
:class:`Request`.
:param headers: (optional) Dictionary of HTTP Headers to send with the
:class:`Request`.
:param cookies: (optional) Dict or CookieJar object to send with the
:class:`Request`.
:param files: (optional) Dictionary of ``'filename': file-like-objects``
for multipart encoding upload.
:param auth: (optional) Auth tuple or callable to enable
Basic/Digest/Custom HTTP Auth.
:param timeout: (optional) How long to wait for the server to send
data before giving up, as a float, or a :ref:`(connect timeout,
read timeout) <timeouts>` tuple.
:type timeout: float or tuple
:param allow_redirects: (optional) Set to True by default.
:type allow_redirects: bool
:param proxies: (optional) Dictionary mapping protocol or protocol and
hostname to the URL of the proxy.
:param stream: (optional) whether to immediately download the response
content. Defaults to ``False``.
:param verify: (optional) Either a boolean, in which case it controls whether we verify
the server's TLS certificate, or a string, in which case it must be a path
to a CA bundle to use. Defaults to ``True``. When set to
``False``, requests will accept any TLS certificate presented by
the server, and will ignore hostname mismatches and/or expired
certificates, which will make your application vulnerable to
man-in-the-middle (MitM) attacks. Setting verify to ``False``
may be useful during local development or testing.
:param cert: (optional) if String, path to ssl client cert file (.pem).
If Tuple, ('cert', 'key') pair.
:rtype: requests.Response
"""
# Create the Request.
req = Request(
method=method.upper(),
url=url,
headers=headers,
files=files,
data=data or {},
json=json,
params=params or {},
auth=auth,
cookies=cookies,
hooks=hooks,
)
prep = self.prepare_request(req)
proxies = proxies or {}
settings = self.merge_environment_settings(
prep.url, proxies, stream, verify, cert
)
# Send the request.
send_kwargs = {
'timeout': timeout,
'allow_redirects': allow_redirects,
}
send_kwargs.update(settings)
resp = self.send(prep, **send_kwargs)
return resp
requests.session()
的基本语法是:
session = requests.session()
session.request(method, url, **kwargs)
首先,实例化session会话对象
其次:
method
:(必填参数)GET
、POST
、HEAD
、PUT
、DELETE
、PATCH
或OPTIONS;
url
:(必填参数)请求的URL地址;**kwargs
:(可选参数)是一个可变的参数类型,在传实参时,以关键字参数的形式传入,python会自动解析成字典的形式;(可选参数,可参考【
requests.request()
】中的**kwargs
)
示例:
这里使用 http://101.43.8.10:6996/ ( ShopXO商城 )
登录接口地址:https://doc.shopxo.net/article/2/336656718643593216.html
我的积分列表接口地址:https://doc.shopxo.net/article/2/288212974584201216.html
若不使用session
,实现代码如下:
import requests
url1 = 'http://101.43.8.10:6996/api.php/user/login'
data1 = {
'accounts': 'laobai',
'pwd': 'laobai123',
'type': 'username'
}
url2 = 'http://101.43.8.10:6996/api.php/userintegral/index'
data2 = {
'page': 1
}
r1 = requests.post(url=url1, data=data1)
r2 = requests.post(url=url2, data=data2, cookies=r1.cookies)
print(r1.json())
print(r2.json())
执行结果:
{'msg': '登录成功', 'code': 0, 'data': {'body_html': ''}}
{'msg': 'success', 'code': 0, 'data': {'total': 0, 'page_total': 0, 'data': []}}
请求我的积分列表接口时,需要增加cookies
参数
若使用session
进行请求:
import requests
url1 = 'http://101.43.8.10:6996/api.php/user/login'
data1 = {
'accounts': 'laobai',
'pwd': 'laobai123',
'type': 'username'
}
url2 = 'http://101.43.8.10:6996/api.php/userintegral/index'
data2 = {
'page': 1
}
session = requests.session()
r1 = session.post(url1, data1)
r2 = session.post(url2, data2)
print(r1.json())
print(r2.json())
执行结果:
{'msg': '登录成功', 'code': 0, 'data': {'body_html': ''}}
{'msg': 'success', 'code': 0, 'data': {'total': 0, 'page_total': 0, 'data': []}}
可以看到我的积分列表接口可以正确的获取接口返回值,即不必传cookies
参数,通过session
即可携带登录cookies
requests.session()
只对cookies
中记录登录状态的有效,若使用token
则无效,还是需要传token
。import requests url1 = 'http://101.43.8.10:6969/api/account/login' data1 = { 'account': '17900000001', 'password': 'a123456', 'client': 2 } session = requests.session() res1 = session.post(url=url1, data=data1) url2 = 'http://101.43.8.10:6969/api/user/center' res2 = session.post(url=url2) print(res2.json())
执行结果:
{'code': -1, 'msg': 'token不能为空', 'data': [], 'show': 1, 'time': '0.042134'}
Requests封装
上面的例子中,requests
的get
请求、post
请求等,都是分别请求的,若测试用例较多时,会有大量的代码冗余,并且在后续的代码异常处理、日志、断言等功能的扩充,代码冗余会更加严重。
在上面的章节中,requests
请求可以通过requests.get
/requests.post
/requests.request
等请求形式进行请求,也可以使用requests.session
进行请求。接下来将会采用requests.session
来学习之后的内容。session
对象可以自动的关联cookies
,这在WEB类型的项目会很方便。
PLRequests.py
import requests
class PLRequests:
# 只要调用这个类,就会进入到init这个函数里面去
def __init__(self):
# 定义session对象
self.session = requests.session()
# 封装请求,这里只对GET、POST、PUT、DELETE四种请求方法做处理
def pl_request(self, method, url, **kwargs):
# 将接受到的method的值统一转为大写字母
method = method.upper()
if 'GET' == method:
resp = self.session.request(method=method, url=url, **kwargs)
elif 'POST' == method:
resp = self.session.request(method=method, url=url, **kwargs)
elif 'PUT' == method:
resp = self.session.request(method=method, url=url, **kwargs)
elif 'DELETE' == method:
resp = self.session.request(method=method, url=url, **kwargs)
else:
raise "请求方法错误"
return resp
# 关闭session对象
def close_session(self):
self.session.close()
改写调用程序如下:
# 导入封装好的LBRequests类,此时就不需要导入requests了
from common.PLRequests import PLRequests
# 实例化LBRequests对象
PLRequests = PLRequests()
url = 'http://101.43.8.10:6996/api.php/user/login'
data = {
'accounts': 'laobai',
'pwd': 'laobai123',
'type': 'username'
}
r = PLRequests.pl_request(method='post', url=url, data=data)
print(r.json())
print(r.url)
print(r.cookies)
执行结果:
{'msg': '登录成功', 'code': 0, 'data': {'body_html': ''}}
http://101.43.8.10/api.php/user/login
<RequestsCookieJar[<Cookie PHPSESSID=08d0442ada4631c6a245d87d56b8b9b2 for 101.43.8.10/>, <Cookie user_login_info=e991MrdJ7Kb%252FrOPAuOH8H8g5hH1rwgdh1ip5Vn3d%252F3DuxiCaglqrMTFYLkFYIUw%252FInQQX2H4v7KFoaZ0pJ8d52vxccKIyhPgWm16uEsLQ3NruB6MOZQ8SEoT9QKb92ePv8HNi%252FYS%252B%252BfIEFn3c5WzLGXUFAcAvd0gApumVgT1nFqBqxiwzJ%252B11aD7KrQWjIhYdgEBL9iYbCedojBssgjN1l4%252FhluyeZe0PXgP0M5GayLN53%252BTMCVCMO0bSe5EP04CmJFM9bx4xM2SdnYk9PFk7AG%252BtveorBfEwovzOYroc0fbXRQ0wYJ6tA48lF5w4uF4uTYIBd6wUi7QjJMxZTjtzA8T9NlcofXKUrQYpyqWkBwKJFRGKWD8%252F8Ufm6fDpYoWFPUQmi6WzDrnPk0wI8kY2JyUcvj0D29inV3YrWju0Ulo9obFYDpAJXv43UAzTpscngS%252FyVAClfFKvdjXOqODVbckZjJYw8x9fxSuivce3SSC5UWa2u%252BbBo8yfbt%252BtzJk%252BilGF0bxBlBsnaMM9XOXN3qr6MGpbH7LHcEQK3S9EVecVGlhTf5AMVoyyMuqAvXkO3wAZM2hMRp9%252FdeVgQCBihIxMLVuJyfs6ICcxWThh0cabtnxfRk5ivwaULT2nwXcdVR4DMcsR41zxWMflwq1lTWZi4cPvvUxK29zcajseU%252FkX%252BpDdY%252BdpPwwXqmKzutT7ZJ%252FGflWs2xdSWhqID6lGktc5XzApNJZ4%252BZmJ7UyGxm1JKhwHt13gct8DndQeGF318vRBmhPYI3786pefSx4CUcQaO0ItcpTvR%252FREwoaiK6T5gHk4yyuWQbTzvYaYfzdE992REtKuVyDhK8Y%252B2W8pzuNjTUmIIxsvV03iJ2gXdnX8N0OajPbU4POgZPTfiBWizjYcKtb6fpfiLO7r19FgL0mi5KO0BKFwoPx8gtEtkKziFe24blksRjg9d0DLDyan9%252FGssl6KcvL6xXoqvKmBZYGMGuSqq%252B2A3V7ULTyT6ZQc5%252FykI5EfauoEgs2BBAZGsG2lETiY1rmBr9yxPXgIC54I9ugiycHaAjouC16Zf3dOP4ZMmccielPFvWnQ%252FjlYVYz7fALgnUrojGb4719rwRVNmvlqlgU2cWUQSp0LstFAK2e5umQeUoS%252Bx4mF3Dau508WPJEWLTIKuEQxYpeynv9tcng0sar8nPRrmqwjQse%252FIlGqGM2B%252FyV5P1v47r0GD7yGRLVXuvGBpc0I5R%252BulIbg85SnK1PHVqeAigYrwd4UthigLWjFzAM9FHxAdwkS6Z4WRiy2%252FgdL%252BPsRcBSENghPFcb%252B9ouDB3ZWp9wd9U%252F2uQF1ifU3WCdGO0VBpA4CLOK0ylS31xFfisqv3ZS05p%252BDZfnWKekP0bWUmC546BqLv7j41noKn5u%252B0KvoTagJpQ%252BFnDkPI%252B31fljSbq8ld6lZtNcwKZRoQ for 101.43.8.10/>, <Cookie uuid=749bc766-39c0-9ba5-cc2e-294b0c235044 for 101.43.8.10/>]>
requests的api.py源代码中如下:
def request(method, url, **kwargs): with sessions.Session() as session: return session.request(method=method, url=url, **kwargs)
可以看到,每次执行
request
都会新建一个session
,多次调用会生成多个session
,所以多个request
请求是没有cookies
关联的。
实例
项目:likeshop商城
网址:http://101.43.8.10:6969/ (H5版)
1、登录接口:
2、商品详情接口:
3、添加到购物车接口:
4、生成订单接口:
5、订单详情接口:
代码实现:
from common.PLRequests import PLRequests
PLRequests = PLRequests()
"""
1、登录接口:
- 接口文档:http://www.likeshop.cn/doc/2/173
- 登录接口:http://101.43.8.10:6969/api/account/login
"""
url1 = 'http://101.43.8.10:6969/api/account/login'
data1 = {
'account': '17900000001',
'password': 'a123456',
'client': 2
}
res1 = PLRequests.pl_request(method='post', url=url1, data=data1)
print(res1.json())
"""
2、商品详情接口:
- 接口文档:http://www.likeshop.cn/doc/2/209
- 登录接口:http://101.43.8.10:6969/api/goods/getGoodsDetail
"""
url2 = 'http://101.43.8.10:6969/api/goods/getGoodsDetail'
params = {
'id': 4
}
res2 = PLRequests.pl_request(method='get', url=url2, params=params)
print(res2.json())
"""
3、添加到购物车接口:
- 接口文档:http://www.likeshop.cn/doc/2/183
- 登录接口:http://101.43.8.10:6969/api/cart/add
"""
url3 = 'http://101.43.8.10:6969/api/cart/add'
data3 = {
'item_id': 1,
'goods_num': 1
}
headers = {
'token': res1.json()['data']['token']
}
res3 = PLRequests.pl_request(method='post', url=url3, data=data3, headers=headers)
print(res3.json())
"""
4、生成订单接口:
- 接口文档:http://www.likeshop.cn/doc/2/272
- 登录接口:http://101.43.8.10:6969/api/order/buy
"""
url4 = 'http://101.43.8.10:6969/api/order/buy'
json = {
"action": "submit",
"goods": [{
"item_id": 1,
"num": 1
}],
"pay_way": 3,
"use_integral": 0,
"type": "cart"
}
res4 = PLRequests.pl_request(method='post', url=url4, json=json, headers=headers)
print(res4.json())
"""
5、订单详情接口:
- 接口文档:http://www.likeshop.cn/doc/2/273
- 登录接口:http://101.43.8.10:6969/api/order/detail
"""
url5 = 'http://101.43.8.10:6969/api/order/detail'
params5 = {
"id": res4.json()['data']['order_id']
}
res5 = PLRequests.pl_request(method='get', url=url5, params=params5, headers=headers)
print(res5.json())
执行结果:
{'code': 1, 'msg': '登录成功', 'data': {'id': 1, 'nickname': '测试账号一', 'avatar': 'http://101.43.8.10:6969/static/common/image/default/user.png', 'level': 1, 'disable': 0, 'distribution_code': 'TVHYKM', 'token': '5754a539eea7c2cd5ca12dc8639bdc23'}, 'show': 0, 'time': '0.093337'}
{'code': 1, 'msg': '获取成功', 'data': {'id': 4, 'name': '晨光文具可削铅笔 六角2B 红黑抽条 木杆铅笔 儿童铅笔 AWP30804', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/4b06036c7e6c8f653a51fd94d4cb5bc5.png', 'video': None, 'remark': '好用', 'content': '<div id="attributes" class="attributes"><div class="attributes-list" id="J_AttrList"><div class="tm-clear tb-hidden tm_brandAttr" id="J_BrandAttr"><div class="name" data-spm-anchor-id="a220o.1000855.0.i3.26c46d7d371Jfl">品牌名称:<span class="J_EbrandLogo" target="_blank" href="//brand.tmall.com/brandInfo.htm?brandId=105529784&type=0&scm=1048.1.1.4">M&G/晨光</span></div></div><p class="attr-list-hd tm-clear"><span>产品参数:</span></p><ul id="J_AttrUL"><li title="M&G/晨光 AWP30804">产品名称:M&G/晨光 AWP30804</li><li id="J_attrBrandName" title=" M&G/晨光">品牌: M&G/晨光</li><li title=" AWP30804">晨光型号: AWP30804</li><li title=" 2B 六角 10支装">颜色分类: 2B 六角 10支装</li><li title=" 石墨/普通铅笔">笔类型: 石墨/普通铅笔</li><li title=" 上海晨光文具股份有限公司">生产企业: 上海晨光文具股份有限公司</li><li title=" 2B">笔芯硬度: 2B</li><li title=" 书写">适用场景: 书写</li><li title=" 10支">支数: 10支</li><li title=" 单色">颜色数: 单色</li><li title=" 棕榈树">笔杆材质: 棕榈树</li><li title=" gb国标标准">安全标准: gb国标标准</li><li title=" 是">是否带橡皮头: 是</li></ul></div></div><div id="mall-banner"><div data-spm="1998132255"></div><div id="J_DescTMS1"></div></div><div id="J_TmpActBanner"></div><div id="J_DcTopRightWrap"><div id="J_DcTopRight" class="J_DcAsyn tb-shop"><div class="J_TModule" data-widgetid="23276204330" id="shop23276204330" data-componentid="5003" data-spm="110.0.5003-23276204330" microscope-data="5003-23276204330" data-title="自定义内容区"><div class="skin-box tb-module tshop-pbsm tshop-pbsm-shop-self-defined"><s class="skin-box-tp"><b></b></s><div class="skin-box-bd clear-fix"><div class="rel" data-title="power by junezx 3.0" data-rn="alnjH"><a class="jsib abs a0Auo-VfMx" data-linkmode="ptlink" data-appid="a0Auo-VfMx"></a><a class="jdb abs a0Auo-weZe" href="https://detail.tmall.com/item.htm?id=627740950878&scene=taobao_shop" target="_blank" data-linkmode="ptlink" data-appid="a0Auo-weZe"></a><a class="jdb abs a0Auo-d9p7" href="https://detail.tmall.com/item.htm?id=631257030944&scene=taobao_shop" target="_blank" data-linkmode="ptlink" data-appid="a0Auo-d9p7"></a><a class="jdb abs a0Auo-95xd" href="https://detail.tmall.com/item.htm?id=600754691350&scene=taobao_shop" target="_blank" data-linkmode="ptlink" data-appid="a0Auo-95xd"></a><a class="jdb abs a0Auo-rTvT" href="https://detail.tmall.com/item.htm?id=591204959642&scene=taobao_shop" target="_blank" data-linkmode="ptlink" data-appid="a0Auo-rTvT"></a><a class="jdb abs a0Auo-Suog" href="https://detail.tmall.com/item.htm?id=611893635921&scene=taobao_shop" target="_blank" data-linkmode="ptlink" data-appid="a0Auo-Suog"></a><a class="jdb abs a0Auo-nrwW" href="https://detail.tmall.com/item.htm?id=571300231971&scene=taobao_shop" target="_blank" data-linkmode="ptlink" data-appid="a0Auo-nrwW"></a></div></div><s class="skin-box-bt"><b></b></s></div></div></div></div><div id="description" class="J_DetailSection tshop-psm tshop-psm-bdetaildes"><div class="content ke-post"><p><img align="absmiddle" src="https://img.alicdn.com/imgextra/i3/682114580/TB2ceIhcW8lpuFjy0FpXXaGrpXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i3/682114580/TB2m0QbcYtlpuFjSspoXXbcDpXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i1/682114580/TB2M.v5c4XlpuFjSsphXXbJOXXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i4/682114580/TB22C7fc80kpuFjSsppXXcGTXXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i2/682114580/TB2oq.fcYVkpuFjSspcXXbSMVXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i3/682114580/TB2K6z6c4XkpuFjy0FiXXbUfFXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i4/682114580/TB2OGIcc90jpuFjy0FlXXc0bpXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i1/682114580/TB29Sn3cYBkpuFjy1zkXXbSpFXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i2/682114580/TB2dOQpc9FjpuFjSszhXXaBuVXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i4/682114580/TB2FkYVc3JkpuFjSszcXXXfsFXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i4/682114580/TB221ZkcYFkpuFjy1XcXXclapXa_!!682114580.jpg" class="img-ks-lazyload"><img align="absmiddle" src="https://img.alicdn.com/imgextra/i3/682114580/TB2pO_7cY0kpuFjy0FjXXcBbVXa_!!682114580.jpg" class="img-ks-lazyload"></p><div><a name="maijsoft_s1_191268_start"></a></div><p>温馨提示:商品外盒或塑封仅作为包装材料使用,在快递运输过程中可能出现不同程度的变形或损坏,均为正常现象,不作为售后理由处理,望亲见谅!</p><div><a name="maijsoft_s1_191268_end"></a></div><div><a name="maijsoft_s1_201186_start"></a></div><p>温馨提示:商品外盒或塑封仅作为包装材料使用,在快递运输过程中可能出现不同程度的变形或损坏,均为正常现象,不作为售后理由处理,望亲见谅!</p></div></div>', 'sales_sum': 43676, 'click_count': 21, 'market_price': '8.00', 'stock': 66532, 'is_collect': 0, 'member_price': 0, 'activity': {'type': 1, 'info': {'id': 3, 'start_time': '14:00', 'end_time': 1672995600}}, 'like': [{'id': 1, 'name': '晨光中性笔笔芯黑0.5mm黑色碳素签字笔GP-1008按动式水笔学生考试用蓝黑医生处方笔教师专用红笔圆珠笔文具', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/45b6bb2224e4051ecf407cabb54cd781.png', 'price': '44.82', 'market_price': '55.00'}, {'id': 3, 'name': '晨光文具经典六角木杆铅笔中小学生考试绘图铅笔 2B铅笔练字笔20支 AWP35715', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/2d62627fef767a38034162c066f9c253.png', 'price': '13.50', 'market_price': '21.00'}, {'id': 8, 'name': 'HERO/英雄钢笔HS208女神钢笔成人女士商务高档礼盒装办公时尚练字女生专用精致送礼官方正品代写贺卡', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/5e11c751c7e662764764e132ab6a8f72.png', 'price': '1359.00', 'market_price': '2598.00'}, {'id': 5, 'name': '小米文具可削铅笔 六角2B 红黑抽条 木杆铅笔 儿童铅笔 AWP30804', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/956e95bc35d0a8005255889036e9aae5.png', 'price': '6.00', 'market_price': '7.00'}, {'id': 2, 'name': '晨光文具速干中性笔直液式签字笔学生考试大容量全针管子弹头水笔直液式笔黑色0.5/0.38', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/5a23d75c44ef8c293aa2a1bed1f10e41.png', 'price': '43.90', 'market_price': '78.00'}], 'price': '6.00', 'goods_spec': [{'id': 4, 'goods_id': 4, 'name': '默认', 'spec_value': [{'id': 4, 'goods_id': 4, 'spec_id': 4, 'value': '默认'}]}], 'goods_item': [{'id': 4, 'goods_id': 4, 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/4b06036c7e6c8f653a51fd94d4cb5bc5.png', 'spec_value_ids': '4', 'spec_value_str': '默认', 'market_price': '8.00', 'price': '6.00', 'stock': 66532}], 'goods_image': [{'goods_id': 4, 'uri': 'http://101.43.8.10:6969/uploads/images/background/20201210/4b06036c7e6c8f653a51fd94d4cb5bc5.png'}, {'goods_id': 4, 'uri': 'http://101.43.8.10:6969/uploads/images/background/20201210/d97a7d56854eb8cd5afa228b1d9608c3.png'}, {'goods_id': 4, 'uri': 'http://101.43.8.10:6969/uploads/images/background/20201210/956e95bc35d0a8005255889036e9aae5.png'}], 'order_give_integral': 0, 'commission_price': 0, 'comment': []}, 'show': 0, 'time': '0.111794'}
{'code': 1, 'msg': '加入成功', 'data': [], 'show': 0, 'time': '0.094376'}
{'code': 1, 'msg': '', 'data': {'order_id': '8', 'type': 'order'}, 'show': 0}
{'code': 1, 'msg': '获取成功', 'data': {'id': 8, 'order_sn': '202301061626104229', 'order_type': 1, 'order_status': 1, 'pay_status': 1, 'pay_way': 3, 'pay_time': '2023-01-06 16:26:10', 'consignee': '老百', 'mobile': '17900000001', 'delivery_type': 1, 'goods_price': '40.00', 'order_amount': '40.00', 'discount_amount': '0.00', 'integral_amount': '0.00', 'total_amount': '40.00', 'total_num': 1, 'shipping_price': '0.00', 'shipping_time': '', 'user_remark': '', 'confirm_take_time': '', 'cancel_time': '', 'refund_status': 0, 'settle_id': 0, 'settle_amount': None, 'use_integral': 0, 'refund_amount': None, 'order_remarks': '', 'create_time': '2023-01-06 16:26:10', 'update_time': None, 'coupon_list_id': None, 'team_found_id': 0, 'team_id': 0, 'delivery_id': 0, 'attach_values': '{"give_integral_scene":1,"give_growth_scene":1,"give_growth_num":0,"give_integral_num":0}', 'team': [], 'order_goods': [{'id': 9, 'order_id': 8, 'goods_id': 1, 'item_id': 1, 'goods_name': '晨光中性笔笔芯黑0.5mm黑色碳素签字笔GP-1008按动式水笔学生考试用蓝黑医生处方笔教师专用红笔圆珠笔文具', 'goods_num': 1, 'goods_price': '40.00', 'member_price': '44.82', 'original_price': '44.82', 'total_price': '40.00', 'total_pay_price': '40.00', 'discount_price': '0.00', 'integral_price': '0.00', 'spec_value_ids': '1', 'refund_status': 0, 'is_comment': 0, 'is_seckill': 1, 'is_member': 0, 'member_discount': '0.00', 'goods_info': '{"item_id":1,"goods_id":1,"goods_name":"晨光中性笔笔芯黑0.5mm黑色碳素签字笔GP-1008按动式水笔学生考试用蓝黑医生处方笔教师专用红笔圆珠笔文具","status":1,"del":0,"image":"\\/uploads\\/images\\/background\\/20201210\\/45b6bb2224e4051ecf407cabb54cd781.png","is_integral":0,"is_member":0,"give_integral_type":0,"give_integral":null,"free_shipping_type":1,"free_shipping":"0.00","free_shipping_template_id":0,"spec_image":"","spec_value_str":"默认","spec_value_ids":"1","goods_price":"40.00","volume":"2.000","stock":9857,"weight":"2.000","first_category_id":1,"second_category_id":4,"third_category_id":9,"goods_num":1,"image_str":"http:\\/\\/101.43.8.10:6969\\/uploads\\/images\\/background\\/20201210\\/45b6bb2224e4051ecf407cabb54cd781.png","is_seckill":1,"discount_price":0,"integral_price":0,"original_price":"44.82","member_price":"44.82","is_show_member":0,"give_integral_num":0,"sub_price":40}', 'create_time': 1672993570, 'comment_btn': 0, 'refund_btn': 0, 'spec_value': '默认', 'image': 'http://101.43.8.10:6969/uploads/images/background/20201210/45b6bb2224e4051ecf407cabb54cd781.png'}], 'delivery_address': '北京北京市东城区东直门内大街1号', 'pay_btn': 0, 'cancel_btn': 0, 'delivery_btn': 0, 'take_btn': 0, 'del_btn': 0, 'order_cancel_time': '', 'pay_way_text': '余额支付'}, 'show': 0, 'time': '0.075669'}