python WEB接口自动化测试之requests库详解

news2024/11/19 15:19:58

 由于web接口自动化测试需要用到python的第三方库--requests库,运用requests库可以模拟发送http请求,再结合unittest测试框架,就能完成web接口自动化测试。

  所以笔者今天先来总结一下requests库的用法。希望对大家(尤其是新手)有帮助哦!大家可要仔细阅读,加油!

1.GET请求

  1.1查看get函数的使用

  1.2 requests的get函数的入参说明

  1.3 requests函数的返回值(http响应)

  1.4举例说明

  1.5用fiddler查看抓包情况

  1.6 get请求总结

2.POST请求

  2.1查看post函数的使用

  2.2 requests的post函数的入参说明

  2.3 requests函数的返回值(http响应)

  2.4举例说明

  2.5用fiddler查看抓包情况

  2.6 post请求总结

3.其他用法

 3.1 定制请求头

 3.2上传文件

 3.3 cookies的发送

4.知识拓展

 4.1关于GET和POST的区别

 4.2关于请求的Headers的Accept-Encoding说明

 4.3关于响应的Headers的Content-Type说明

 4.4关于requests资料相关地址 

前提:

requests库是python的第三方库,需要提前安装哦,可以直接用pip命令:python –m pip install requests

按照惯例,先将requests库的属性打印出来,看看哪些属性。

>>> import requests

>>> dir(requests)               #查看requests库的属性

['ConnectionError', 'HTTPError', 'NullHandler', 'PreparedRequest', 'Request', 'RequestException', 'Response', 'Session', 'Timeout', 'TooManyRedirects', 'URLRequired', '__author__', '__build__', '__builtins__', '__copyright__', '__doc__', '__file__', '__license__', '__name__', '__package__', '__path__', '__title__', '__version__', 'adapters', 'api', 'auth', 'certs', 'codes', 'compat', 'cookies', 'delete', 'exceptions', 'get', 'head', 'hooks', 'logging', 'models', 'options', 'packages', 'patch', 'post', 'put', 'request', 'session', 'sessions', 'status_codes', 'structures', 'utils']

所以可以看到requests的属性有get,post,delete,put,对应http请求的method方法。

常用的是get和post请求。get请求一般是查询获取资源信息。post一般是更新资源信息。

1.GET请求

点击返回目录

1.1查看get函数的使用

>>> help(requests.get)          #查看requests库的属性get请求函数的使用

Help on function get in module requests.api:

get(url, params=None, **kwargs)

    Sends a GET request.

    :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 \*\*kwargs: Optional arguments that ``request`` takes.

    :return: :class:`Response <Response>` object

    :rtype: requests.Response

1.2 requests的get函数的入参说明

url:调用接口的URL地址。

params:为可选参数,该参数是一个字典类型。数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。举例说明,若r=requests.get("http://httpbin.org/get",params={'key1':'value1','key2':'value2'}) 那么,最终请求的目标URL为http://bin.org/get?key1=val1& key2=val2。

**kwargs:其他可选参数,例如headers,files,cookies,auth,timeout,json等。

例如:auth=(‘username',’password’):接口安全测试中用到的用户认证。

例如:headers = {'user-agent': 'my-app/0.0.1'}:可定制发送请求头。

1.3 requests函数的返回值(http响应)

返回的是response类对象(requests.models.Response)。来自requests模块 models.py里的Response类

>>> r=requests.get('http://httpbin.org/get')  #查看response的属性

>>> dir(r)

['__attrs__', '__bool__', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getstate__', '__hash__', '__init__', '__iter__', '__module__', '__new__', '__nonzero__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_content', '_content_consumed', 'apparent_encoding', 'close', 'connection', 'content', 'cookies', 'elapsed', 'encoding', 'headers', 'history', 'is_permanent_redirect', 'is_redirect', 'iter_content', 'iter_lines', 'json', 'links', 'ok', 'raise_for_status', 'raw', 'reason', 'request', 'status_code', 'text','url']

对于返回对象常用的属性如下:

json():生成json数据对象的方法。如果 JSON 解码失败, r.json 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json 将会抛出 ValueError: No JSON object could be decoded 异常。

status_code:响应状态码。

encoding:编码,如utf-8。

url:目标url。

headers:响应头。类型为字典类型,若键不存在则返回None。

text:响应内容。字符串方式,会自动根据响应头部的字符编码进行解码。如果你改变了编码r.encoding,每当你访问 r.text ,Request 都将会使用 r.encoding 的新值。

content:二进制响应内容。字节方式,会自动为你解码gzip和deflate压缩。

raw:原始响应内容,也就是 urllib 的 response 对象,请求中要加stream=True,再使用 r.raw.read() 读取。

r.raise_for_status:失败请求(非200响应)抛出异常。

1.4举例说明

>>> payload={'key1':'value1','key2':'value2'}
>>> r=requests.get("http://httpbin.org/get",params=payload)
>>> r.status_code
200
>>> r.json()

{u'origin': u'113.98.252.236', u'headers': {u'Host': u'httpbin.org', u'Accept-Encoding': u'gzip, deflate', u'Accept': u'*/*', u'User-Agent': u'python-requests/2.7.0 CPython/2.7.11 Windows/7'}, u'args': {u'key2': u'value2', u'key1': u'value1'}, u'url': u'http://httpbin.org/get?key2=value2&key1=value1'}

>>> r.url  #url:params数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。
u'http://httpbin.org/get?key2=value2&key1=value1'
>>> r.headers

{'content-length': '334', 'server': 'nginx', 'connection': 'keep-alive', 'access-control-allow-credentials': 'true', 'date': 'Fri, 09 Dec 2016 09:04:40 GMT', 'access-control-allow-origin': '*', 'content-type': 'application/json'}

>>> r.headers['content-type']
'application/json'
>>> r.raw
<requests.packages.urllib3.response.HTTPResponse object at 0x0000000002E64E10>
>>> r.cookies
<RequestsCookieJar[]>
>>> r.text

u'{\n "args": {\n "key1": "value1", \n "key2": "value2"\n }, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n }, \n "origin": "113.98.252.236", \n "url": "http://httpbin.org/get?key2=value2&key1=value1"\n}\n'

>>> r.content

'{\n "args": {\n "key1": "value1", \n "key2": "value2"\n }, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n }, \n "origin": "113.98.252.236", \n "url": "http://httpbin.org/get?key2=value2&key1=value1"\n}\n'

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.get("http://httpbin.org/get", params=payload,stream=True)

>>> r.raw

<requests.packages.urllib3.response.HTTPResponse object at 0x0000000003105940>

>>> r.raw.read()

'{\n  "args": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n  }, \n  "origin": "113.98.252.236", \n  "url": "http://httpbin.org/get?key2=value2&key1=value1"\n}\n'

1.5用fiddler查看抓包情况

r.json():json数据,可以看出与1.4中的r.json()值一致。

r.headers:响应头数据,可以看出与1.4中r.headers值一致。

r.raw:响应原始数据

1.6 get请求总结

    综上所述,通过requests.get("某url",params={字典类型参数键值对})模拟浏览器发送一个http的请求(其中请求的方法是get,请求的url地址如下形式

http://httpbin.org/get?key2=value2&key1=value1),服务器处理数据后,会返回一个response对象,通过读取response对象的属性值,如json数据,可以做一系列的断言,从而验证该接口返回的数据是否正确。

2.POST请求

点击返回目录

2.1查看post函数的使用

>>> help(requests.post)          #查看requests库的属性post请求函数的使用

post(url, data=None, json=None, **kwargs)
Sends a POST request.

:param url: URL for the new :class:`Request` object.
:param data: (optional) Dictionary, 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

2.2 requests的post函数的入参说明

url:调用接口的URL地址。

data:为可选参数,该参数是一个字典类型。

json:为可选参数,该参数是一个json类型。

**kwargs:其他可选参数,例如headers等。

2.3 requests函数的返回值(http响应)

同1.3

json():生成json数据对象的方法。如果 JSON 解码失败, r.json 就会抛出一个异常。例如,响应内容是 401 (Unauthorized),尝试访问 r.json 将会抛出 ValueError: No JSON object could be decoded 异常。

status_code:响应状态码。

encoding:编码,如utf-8。

url:目标url。

headers:响应头。类型为字典类型,若键不存在则返回None。

text:响应内容。字符串方式,会自动根据响应头部的字符编码进行解码。如果你改变了编码r.encoding,每当你访问 r.text ,Request 都将会使用 r.encoding 的新值。

content:二进制响应内容。字节方式,会自动为你解码gzip和deflate压缩。

raw:原始响应内容,也就是 urllib 的 response 对象,请求中要加stream=True,再使用 r.raw.read() 读取。

r.raise_for_status:失败请求(非200响应)抛出异常。

2.4举例说明

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("http://httpbin.org/post", data=payload)

>>> r.status_code

200

>>> r.json()

{u'files': {}, u'origin': u'113.98.252.236', u'form': {u'key2': u'value2', u'key1': u'value1'}, u'url': u'http://httpbin.org/post', u'args': {}, u'headers': {u'Content-Length': u'23', u'Accept-Encoding': u'gzip,deflate', u'Accept': u'*/*', u'User-Agent': u'python-requests/2.7.0 CPython/2.7.11 Windows/7', u'Host': u'httpbin.org', u'Content-Type': u'application/x-www-form-urlencoded'}, u'json': None, u'data': u''}

>>> r.url

u'http://httpbin.org/post'

>>> r.headers

{'content-length': '461', 'server': 'nginx', 'connection': 'keep-alive', 'access-control-allow-credentials': 'true', 'date': 'Mon, 12 Dec 2016 02:46:14 GMT', 'access-control-allow-origin': '*', 'content-type': 'application/json'}

>>> r.headers['content-type']

'application/json'

>>> r.raw

<requests.packages.urllib3.response.HTTPResponse object at 0x0000000002EE4A58>

>>> r.text

u'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n  }, \n  "json": null, \n  "origin": "113.98.252.236", \n  "url": "http://httpbin.org/post"\n}\n'

>>> r.content

'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n  }, \n  "json": null, \n  "origin": "113.98.252.236", \n  "url": "http://httpbin.org/post"\n}\n'

>>> payload = {'key1': 'value1', 'key2': 'value2'}

#获取原始响应内容

>>> r = requests.post("http://httpbin.org/post", data=payload,stream=True)

>>> r.raw

<requests.packages.urllib3.response.HTTPResponse object at 0x0000000003105208>

>>> r.raw.read()

'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "23", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n  }, \n  "json": null, \n  "origin": "113.98.252.236", \n  "url": "http://httpbin.org/post"\n}\n'

#使用 json 参数直接传递

>>> payload = {'key1': 'value1', 'key2': 'value2'}

>>> r = requests.post("http://httpbin.org/post", json=payload)

>>> r.text

u'{\n  "args": {}, \n  "data": "{\\"key2\\": \\"value2\\", \\"key1\\": \\"value1\\"}", \n  "files": {}, \n  "form": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "36", \n    "Content-Type": "application/json", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n  }, \n  "json": {\n    "key1": "value1", \n    "key2": "value2"\n  }, \n  "origin": "113.98.252.236", \n  "url": "http://httpbin.org/post"\n}\n'

2.5用fiddler查看抓包情况

r.json():json数据,可以看出与2.4中的r.json()值一致。

注:通过json进行传参的json数据

r.headers:响应头数据,可以看出与2.4中r.headers值一致。

r.raw:响应原始数据

2.6 post请求总结

    综上所述,通过requests.post("某url",data={字典类型参数键值对})模拟浏览器发送一个http的请求(其中请求的方法是post,请求的url地址如下形式

http://httpbin.org/get),服务器处理数据后,会返回一个response对象,通过读取response对象的属性值,如json数据,可以做一系列的断言,从而验证该接口返回的数据是否正确。

3.其他用法

点击返回目录

3.1 定制请求头

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> headers = {'user-agent': 'my-app/0.0.1'}
>>> r = requests.post("http://httpbin.org/post", data=payload,headers=headers)

用fiddler抓包,可以看到,发送请求的请求头中的user-agent的值为设置的值。

注意: 所有的 header 值必须是 string、bytestring 或者 unicode。

3.2上传文件

>>> import os

>>> os.getcwd()

'D:\\pythontest'

>>> f=open('1.txt','w+')

>>> f.write('test') 

>>> os.listdir('D:\\pythontest')

['1.txt',]

>>> import requests

>>> url = 'http://httpbin.org/post'

>>> files = {'file': open('1.txt', 'rb')}

>>> r = requests.post(url, files=files) 

>>> r.text

u'{\n  "args": {}, \n  "data": "", \n  "files": {\n    "file": ""\n  }, \n  "form": {}, \n  "headers": {\n    "Accept": "*/*", \n    "Accept-Encoding": "gzip, deflate", \n    "Content-Length": "141", \n    "Content-Type": "multipart/form-data; boundary=37de3eb22a754f34849771891b77bd23", \n    "Host": "httpbin.org", \n    "User-Agent": "python-requests/2.7.0 CPython/2.7.11 Windows/7"\n  }, \n  "json": null, \n  "origin": "113.98.252.236", \n  "url": "http://httpbin.org/post"\n}\n'

用fiddler抓包,可以看到,响应的JSON数据中有file。

3.3 cookies的发送

>>> url = 'http://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')
>>> r = requests.get(url, cookies=cookies)
>>> r.text
u'{\n "cookies": {\n "cookies_are": "working"\n }\n}\n'

4.知识拓展

点击返回目录

4.1关于GET和POST的区别

    通过上面抓包可以看出:

    GET请求的数据会附在URL之后(就是 把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连,如:login.action?name=hyddd& password=idontknow&verify=%E4%BD%A0%E5%A5%BD。如果数据是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以 16进制表示的ASCII。

    POST把提交的数据则放置在是HTTP包的包体中。

4.2关于请求的Headers的Accept-Encoding说明

请求的headers中的client项中的Accept-Encoding的,例如Accept-Encoding: gzip, deflate。浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate)(注意:这不是只字符编码)。

4.3关于响应的Headers的Content-Type说明

Content-Type是返回消息中非常重要的内容,表示后面的文档属于什么MIME类型。

Content-Type: [type]/[subtype]; parameter。例如最常见的就是text/html,它的意思是说返回的内容是文本类型,这个文本又是HTML格式的。原则上浏览器会根据 Content-Type来决定如何显示返回的消息体内容。

type有下面的形式:

Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;

Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;

Application:用于传输应用程序数据或者二进制数据;

Message:用于包装一个E-mail消息;

Image:用于传输静态图片数据;

Audio:用于传输音频或者音声数据;

Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。

subtype用于指定type的详细形式。

parameter可以用来指定附加的信息,更多情况下是用于指定text/plain和text/htm等的文字编码方式的charset参数。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1442807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用CICFlowMeter 实现对pcap文件的特征提取【教程】

使用CICFlowMeter 实现对pcap文件的特征提取【教程】 针对现有的关于CICFlowMeter 的使用教程不够全面&#xff0c;一些细节没有展示&#xff0c;我将结合网络上的相关资料和实际的经历&#xff0c;提供一些经验和建议。 configuration information --------------- Windows…

hexo部署到gitee(码云)

引言 Hexo 是一个基于Node.js的静态博客框架&#xff0c;而 Gitee&#xff08;也被称为码云&#xff09;是一个国内的代码托管平台&#xff0c;支持 Git 版本控制系统&#xff0c;与 GitHub 类似。将 Hexo 部署到 Gitee Pages 可以让你的博客受益于 Gitee 的国内服务器&#xf…

详解计算机软件基本概念

软件基本概念 软件的定义 一个完整的计算机系统是由硬件系统和软件系统协同工作来完成某一给定的任务的。 只有硬件的计算机称为裸机&#xff0c;裸机必须安装了计算机软件后才可以完成各项任务。 从广义地讲&#xff0c;软件是指计算机程序、数据以及开发、使用和维护程序…

Go语言安全编码:crypto/sha1库全面解析

Go语言安全编码&#xff1a;crypto/sha1库全面解析 简介SHA-1基础原理和特点SHA-1与其他哈希算法的比较代码示例&#xff1a;基本的SHA-1哈希生成 使用crypto/sha1处理数据处理字符串和文件的SHA-1哈希代码示例&#xff1a;为文件生成SHA-1哈希 常见错误和最佳实践 在实际项目中…

烟雨要饭网带后台,附带搭建教程

直接上传访问即可&#xff0c;有安装向导&#xff0c;php环境不得低于7.0 后台地址/Admin&#xff0c;默认账号admin 默认密码123456 自带乞讨音乐&#xff0c;增加樱花特效

《乱弹篇(十二)聊春晚》

龙年大初一&#xff0c;老龄笔者发表《乱弹篇&#xff08;十二&#xff09;》。“十二”的标志&#xff0c;乃好事成双“二”。喜庆有余&#xff0c;自不待言&#xff01; 除夕夜我没有看春晚&#xff0c;是在继续追剧&#xff0c;即以明朝宫廷内斗为背景的电视连续剧《后宫》…

【原理图PCB专题】Cadence17.4版本新增加的Cutout和Design_Outline层有什么用?

在Cadence 17.4版本中我们发现在Board Geometry下面多出了Cutout和Design_Outline两层,其实这两层在高版本的软件中都做为板框使用。 如下所示在输出光绘时,如果没有将Cutout和Desing_Outline两层加入,还是使用16版本的Outline来定义板框的话,在出光绘时会提示:WA…

备战蓝桥杯---搜索(进阶1)

话不多说&#xff0c;直接看题&#xff1a; 没有传送带时&#xff0c;我们可以直接BFS&#xff0c;但因为传送带的出现&#xff0c;可能在队列里的元素到起点时间不单调的问题&#xff0c;而BFS本来就是可以看成随着时间推移而产生的情况&#xff0c;于是我们把队列看成优先队列…

Matlab使用点云工具箱进行点云配准ICP\NDT\CPD

一、代码 主代码main.m&#xff0c;三种配准方法任选其一 % 读取点云文件 source_pc pcread(bun_zipper.ply); target_pc pcread(bun_zipper2.ply);% 下采样 ptCloudA point_downsample(source_pc); ptCloudB point_downsample(target_pc);% 配准参数设置 opt param_set…

有关网络安全的课程学习网页

1.思科网络学院 免费学习skillsforall的课程 课程链接&#xff1a;Introduction to Cybersecurity by Cisco: Free Online Course (skillsforall.com) 2.斯坦福大学计算机和网络安全基础 该证书对于初学者来说最有价值&#xff0c;它由最著名的大学之一斯坦福大学提供。您可…

卫星通讯领域FPGA关注技术:算法和图像方面(1)

最近关注的公众号提到了从事移动通信、卫星通讯等领域的FPGA、ASIC、信号处理算法等工程师可能需要关注的技术&#xff0c;有LMS算法、RLS算法、LCMV算法、SAR图像处理&#xff0c;以下做了一些基础的调研&#xff1a; 1 LMS算法&#xff1a; LMS&#xff08;Least Mean Squa…

springboot170图书电子商务网站的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

elasticsearch下载及可视化工具下载使用

elasticsearch下载及配置、启动 一、下载 Download Elasticsearch | Elastic 二、启动 双击bat即可。 出现如下说明启动成功&#xff1a; 访问测试&#xff1a; 三、注意 &#xff08;1&#xff09;因为es启动默认端口是&#xff1a;9200,所以需要检查此端口是否被占用。…

unity-ios-解决内购商品在Appstore上面已配置,但在手机测试时却无法显示的问题

自己这几天用 unity 2021 xcode 14.2 开发ios内购&#xff0c;appstore上面内购商品都已经配置好了&#xff0c;但是在手机里就是不显示&#xff0c;最后才发现必需得满足以下条件才行&#xff1a; 1. Appstore后台 -> 内购商品 -> 商品状态必需为『准备提交』以上状态…

【万题详解】洛谷P1282 多米诺骨牌

题目 链接——题目在这里&#xff01;&#xff01;&#xff01; 多米诺骨牌由上下 22 个方块组成&#xff0c;每个方块中有 1∼6 个点。现有排成行的上方块中点数之和记为 S1​&#xff0c;下方块中点数之和记为 S2​&#xff0c;它们的差为 ∣∣S1​−S2​。如图S161119&…

最佳视频转换器软件:2024年视频格式转换的选择

我们生活在一个充满数字视频的世界&#xff0c;但提供的内容远不止您最喜欢的流媒体服务目录。虽然我们深受喜爱的设备在播放各种自制和下载的视频文件方面变得越来越好&#xff0c;但在很多情况下您都需要从一种格式转换为另一种格式。 经过大量测试&#xff0c; 我们尝试过…

谷歌发布AI新品Gemini及收费模式;宜家推出基于GPT的AI家装助手

&#x1f989; AI新闻 &#x1f680; 谷歌发布AI新品Gemini及收费模式 摘要&#xff1a;谷歌宣布将原有的AI产品Bard更名为Gemini&#xff0c;开启了谷歌的AI新篇章。同时推出了强化版的聊天机器人Gemini Advanced&#xff0c;支持更复杂的任务处理&#xff0c;提供了两个月的…

【MySQL】数据库基础 -- 详解

一、什么是数据库 存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 一般的文件确实提供了数据的存储功能&#xff0c;但是文件并没有提供非常好的数据&#xff08;内容&#xff09;的管理能力&#xff08;用户角度&#xff09;。 文件保存数据有以下几个缺点&…

《MySQL 简易速速上手小册》第8章:事务管理和锁定策略(2024 最新版)

文章目录 8.1 理解 MySQL 中的事务8.1.1 基础知识8.1.2 重点案例&#xff1a;使用 Python 实现银行转账事务8.1.3 拓展案例 1&#xff1a;处理并发事务8.1.4 拓展案例 2&#xff1a;使用 Python 监控事务状态 8.2 锁定机制和事务隔离级别8.2.1 基础知识讲解8.2.2 重点案例&…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(12)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;11&#xff09; 4.2 PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线&#xff0c;其作用与PCI总线类似&#xff0c;主要目的是为了连接处理器系统中的外部设备…