使用 PHP、JavaScript 和 WURFL 的设备识别移动网站

news/2024/5/20 14:16:50/文章来源:https://blog.csdn.net/chamtianjiao/article/details/36877729


不再为移动设备功能而迷茫

随着移动 Web 的快速发展,如果您还没有使用过 PHP 驱动的移动网站或应用程序,那么您很快就会用到。在数以千计的产品中检测一个移动设备的功能,仅使用 PHP 几乎是不可能实现的。但是有了 Wireless Universal Resource FiLe (WURFL) 之后,这个曾经令人生畏的艰巨任务变得像调用几个 API 来检索您需要的设备数据一样简单,并且可以与您的 PHP 站点和应用程序一起使用。

Chad Russell, 软件工程师兼顾问, 自由职业

2012 年 5 月 25 日

  • +内容

随着移动计算在其设备数量以及设备用户数量方面不断的增长,越来越多的移动仅有或移动特定网站和 Web 应用程序正在开发中。跟踪所有这些设备、设备的操作系统版本、每个设备的功能等等,都可能是一项艰巨的任务。现代移动浏览器结合了诸如 HTML5 和 CSS3 等新兴标准和技术,使专用设备少了许多后顾之忧。然而,很多特质仍然存在,而且可能永远存在于这些设备中,拥有这些信息为您所用,其价值将是无可估量的。

尽管一些基本的任务(比如,浏览器检测)可以使用 PHP 或者 JavaScript 轻易地完成,但是,在关于使用移动设备访问您的站点或应用程序的可能性方面仍然存在许多未知数。能够检测一个设备是否支持 Adobe® Flash®,检测该设备可以使用哪个 Ajax,或者检测它是否支持 CSS spriting,这些未必是您使用 PHP 或 JavaScript 可以快速确定的。

然而,使用 Wireless Universal Resource File(WURFL 发音为 “were-full”)可以轻松地调整您的移动站点和应用程序,因为您能确切地知道该设备可以做什么,不可以做什么。但如果没有 WURFL,这项任务的确是个挑战,但并不是不可能完成的。

WURFL 是什么?

从 WAP 到 WURFL

大约在 2001 年左右,最初的 Wireless Access Protocol (WAP) 电话上市几年之后,很明显,支持 WAP 的设备在处理 WAP 内容方面有很大差异。因此,两个富于创业精神的开发员(Luca Passani 和 Andrea Trasatti)走在一起构建了一个有关共享设备存储库的开源社区,他们将其称之为 WURFL。如今,10 年过去了,WURFL 也在不断增长,存储库中的设备数量以及提供的编程语言 API 都在不断增长。

WURFL 是一个由 ScientiaMobile 运行的开源 Device Description Repository (DDR) 项目,旨在成为移动设备信息的一个独立中央存储库。目前被 Facebook 和 Google 以及其他很多大小型企业所用。诸如有关正使用的移动浏览器的制造和版本信息、设备是否是平板,该设备是否能支持 Flash 等宝贵信息都可在 WURFL 中找到。

简单来说,WURFL 就是包含数千个移动设备及其各自功能的一个存储库。DDR 是由一个 XML 配置文件构成,搭配一组 API,这些 API 使您只需做少量的工作即可检索关于给定移动设备的海量信息。使用 WURFL PHP API,您就可以马上轻松地在您的移动 PHP 开发中使用 WURFL。

探索 WURFL

我们已经探讨了许多关于为什么使用 WURFL 以及它能实现什么的内容。现在我们来探讨一下 WURFL 中的数据是什么样的,以及使用它您有获得有关设备的何种信息。

在开始使用 DDR 和 WURFL PHP API 之前,您自己应该先熟悉一下 WURFL 中的数据类型。记住,WURFL 最简单的格式是一个 XML 文件:打开 WURFL 文件时,可以看到所有数据都在一组 XML 节点中组成。在 WURFL 文件中有许多节点,但是能找到有关给定移动设备的数据只有 3 个节点。表 1 显示了这些设备节点。

表 1. 主要 WURFL 设备节点
节点描述示例数据
<device>包含给定设备信息的主要节点<device id="htc_incredible_adr6300_ver1" user_agent="Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; ADR6300 Build/ERE27) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2" fall_back="generic_android_ver2_1" actual_device_root="true">
<group>设备节点的子节点;包含有关定义特性的信息<group id="display">
<capability>组节点的子节点;列出给定设备的各个功能,在某个给定组中指定。<capability name="physical_screen_height" value="80"/>
<capability name="physical_screen_width" value="48"/>

从表 1 中,您可以确定每个设备的基本 XML 结构:

<device><group><capability /><capability /><capability /></group><group><capability /><capability /><capability /></group>
</device>

例如,如果您查看 WURFL 的内部,您会看到 Apple iPhone 4 设备的条目,如 清单 1 所示。

清单 1. iPhone 4 WURFL 条目
 <device id="apple_iphone_ver4" user_agent="Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/7D11" fall_back="apple_iphone_ver3_1_3" actual_device_root="true"> <group id="product_info"> <capability name="model_name" value="iPhone"/> <capability name="device_os_version" value="4.0"/> <capability name="model_extra_info" value="4.0"/> <capability name="release_date" value="2010_april"/> </group> <group id="playback"> <capability name="playback_acodec_aac" value="lc"/> <capability name="playback_mp4" value="true"/> <capability name="playback_3gpp" value="true"/> <capability name="playback_acodec_amr" value="nb"/> <capability name="playback_acodec_qcelp" value="false"/> <capability name="playback_vcodec_mpeg4_sp" value="3"/> <capability name="playback_vcodec_h263_0" value="30"/> <capability name="playback_3g2" value="true"/> <capability name="playback_vcodec_h264_bp" value="3.0"/> </group> <group id="streaming"> <capability name="streaming_vcodec_h263_0" value="30"/> <capability name="streaming_acodec_aac" value="lc"/> <capability name="streaming_3gpp" value="true"/> <capability name="streaming_vcodec_h264_bp" value="3.0"/> <capability name="streaming_acodec_amr" value="nb"/> <capability name="streaming_preferred_protocol" value="http"/> <capability name="streaming_vcodec_mpeg4_sp" value="3"/> <capability name="streaming_mp4" value="true"/> </group> 
</device>

从该示例中,您可以看到,主设备节点中有 2 个子组节点为 iPhone 4 条目。这两个子节点提供关于该设备所支持的音频和视频编解码器的详细信息。但是等等,这里不应该包含更多信息吗,比如设备是否支持 Flash 或 PDF 或它是否是一个平板电脑?当然!实际上,您可以在 WURFL 中找到这些信息,但是由于 WURFL 的性质以及它在存储库已有设备信息上的构建方式,在这个条目中显然是没有这些信息的。

由于 WURFL 包含数千个设备规格以及每个设备各自的功能,所以它可以快速成为一个不断增长的复杂数据阵列,以继续进行构建和维护。然而,WURFL 的智慧体现在它管理这一复杂性的方法。

WURFL 的创建者已将有关移动设备的以下事实进行考量:

  • 尽管浏览器不同,但是有很多相同的特性。
  • 来自同一制造商的浏览器和设备总是从同一硬件和软件发展而来的。从对 Motion BlackBerry Curve 9350、9360 和 9370 的研究来看:它们之间的共性很多,并且差异非常小。
  • 来自不同制造商的设备可能运行相同的软件。例如,HTC、Motorola 和 Samsung 所有设备都运行 Google Android 操作系统,都有一个基于开源 WebKit 和 Google Chrome' 的 V8 JavaScript 引擎的浏览器。因此,在大多数情况下,每个设备就浏览器支持而言都是相似的。

把所有这些都纳入考量,能够降低 WURFL 的复杂性,并易于维护人员执行更新。本质上,WURFL 是基于一个设备系列的概念。如果您查看 WURFL 文件中的第一个设备,可以看到一个 ID 为 generic 的设备。WURFL 文件中的一切都是基于这个 generic 设备构建的。当添加一个新设备时,如果该设备属于既有设备系列,它将继承该系列的所有功能,除非该设备有特别的不同,与此同时,该信息会将被添加到给定设备中。

例如,如果您查看 清单 1 中 iPhone 4 示例 <device> 节点的 fall_back 属性,您会看到它引用了 apple_iphone_ver3_1_3(WURFL 中已有 iPhone 设备条目的设备 ID 属性)。如果您继续以此 ID 跟进,最终将会获得一个属性 ID 为 apple_iphone_ver1 的设备节点。沿着这个过程,您会找到更多的设备信息,比如它的首选地理定位 API、是否支持 Adobe Flash Light,以及显示分辨率。清单 2 提供了一些您将找到的组节点。

清单 2. 在 WURFL 找到的设备组
<group id="ajax"> <capability name="ajax_preferred_geoloc_api" value="w3c_api"/> 
</group>
<group id="display"> <capability name="resolution_height" value="480"/> <capability name="resolution_width" value="320"/> 
</group>
<group id="flash_lite"> <capability name="flash_lite_version" value=""/> <capability name="fl_wallpaper" value="false"/> <capability name="fl_browser" value="false"/> <capability name="fl_screensaver" value="false"/> <capability name="fl_standalone" value="false"/> <capability name="fl_sub_lcd" value="false"/> 
</group>

设备

正如您在 iPhone4 WURFL 条目中所看到的,给定设备的每个规范以主 <device> 节点开始。这些节点通常包含用户代理字符串属性,一个 fall_back 设备属性,以及一个惟一的 ID 属性。

WURFL 包含了大量的数据组。这些数据组是设备节点的子节点,其中每个子节点均定义了一个设备可能支持或不支持的功能,以及有关在组节点中找到的功能的更多详细信息。您在 WURFL 中能找到的数据组有:product_infowml_uichtml_ui>xhtml_uihtml_uicssajaxmarkupcachedisplayimage_formatbugswtasecuritybearerstorageobject_downloadplaybackwap_pushdrmstreamingmmsj2mesmssound_formatflash_litetranscodingrsspdfchipssmarttvdeprecated

在 WURFL 帮助文档中找到最新的数据组列表以及每个数据组的完整描述(包含有关在给定组中定义的功能的表格分项,比如功能名称、类型和描述)(参见 参考资料 获取相关链接)。

功能

功能是其父组中定义的。所有功能名称属性均是惟一的,即使数据组之间也是惟一的,因此,在一个设备规范中功能名称不会多次出现。此外,功能都会有一个值,该功能值可以是布尔值、字符串(甚至是空字符串)或者数字。

清单 3 提供了您可以在 WURFL 中找到的实际组示例(包含其定义的功能)。

清单 3. WURFL product_info 组及其功能
 <group id="product_info"> <capability name="pointing_method" value="touchscreen"/> <capability name="uaprof" value="http://www.blackberry.net/go/mobile/profiles/uaprof/9500_edge/4.7.0.rdf"/> <capability name="model_name" value="BlackBerry 9500"/> <capability name="brand_name" value="RIM"/> <capability name="model_extra_info" value="Thunder"/> <capability name="marketing_name" value="Storm"/> 
</group>

在这里,您拥有最常见的组 product_info。正如您所看到的,您可以找到关于该设备的基本信息,比如模型和商标,以及此设备是否有触摸屏和用户代理配置文件。

另一个常见组是 display,如 清单 4 所示,提供关于设备屏幕尺寸和分辨率的详细信息。如果您想要在一个给定设备上正确显示一个移动网站或者 Web 应用程序,而不是全凭猜想,那么这些信息是非常有帮助的。

清单 4. 在 WURFL 中查找设备屏幕信息
<group id="display"> <capability name="physical_screen_height" value="66"/> <capability name="columns" value="36"/> <capability name="dual_orientation" value="true"/> <capability name="physical_screen_width" value="50"/> <capability name="max_image_width" value="340"/> <capability name="rows" value="32"/> <capability name="resolution_width" value="360"/> <capability name="resolution_height" value="480"/> <capability name="max_image_height" value="440"/> 
</group>

有了这 2 个组,您就可看到,该设备支持 PDF 文档(见 清单 5),以及 Java™ 2 平台和 Mobile Edition (J2ME)。此外,您会再一次明白拥有这些信息是多么的重要,在您随意连接设备,不需要测试或者花费额外时间来编写代码来检查这些特性。

清单 5. 检查一个给定设备的 PDF 支持
<group id="pdf"> <capability name="pdf_support" value="true"/> 
</group> 
<group id="j2me"> <capability name="j2me_midp_2_0" value="true"/> <capability name="j2me_cldc_1_0" value="true"/> <capability name="j2me_cldc_1_1" value="true"/> <capability name="j2me_midp_1_0" value="true"/> 
</group>

使用 PHP API

WURFL 项目中提供的 PHP API 使得您可以轻易地在 PHP 开发中使用 WURFL。(参见 参考资料 获取相关链接以下载 WURFL PHP API 最新版本。)以下简单的示例演示了如何快捷方便地检索一个给定移动设备的功能。

例如,您可以使用 getCapability 方法传入在 WURFL 中找到的一些不同的功能名称。您可以检索商标与型号名称,设备的分辨率,以及设备是否支持 PDF 和 Flash。该示例假设您已经下载 WURFL PHP API,并将其提取到 Web 服务器根目录中;您可以在 清单 6 中找到代码,在顶层 WURFL PHP API 目录下的 demo 目录中。

清单 6. PHP API 示例的 Demo 代码
<?phpdefine("WURFL_DIR", dirname(__FILE__) . '/../../WURFL/'); 
define("RESOURCES_DIR", dirname(__FILE__) . "/../resources/"); require_once WURFL_DIR . 'Application.php'; $wurflConfigFile = RESOURCES_DIR . 'wurfl-config.xml'; // Create WURFL Configuration from an XML config file 
$wurflConfig = new WURFL_Configuration_XmlConfig($wurflConfigFile); // Create a WURFL Manager Factory from the WURFL Configuration 
$wurflManagerFactory = new WURFL_WURFLManagerFactory($wurflConfig); // Create a WURFL Manager ($wurflManager is a WURFL_WURFLManager object) 
$wurflManager = $wurflManagerFactory->create();

获取最新的 WURFL 存储库

您可以在该项目的 SourceForge 页面中找到最新版本的 WURFL(参见 参考资料 获取相关链接)。一旦您在 PHP 应用程序中开始使用 DDR,就要确保您所使用的版本是最新的。更新 WURFL 很容易:只需要下载最新版本并替换已有的 wurfl.xml 文件即可。尽管批处理文件可用,但还是推荐替换现有的 wurfl.xml 文件。

首先,创建到 application.php 文件以及 WURFL XML 文件的相应路径。然后,创建 WURFL Manager 对象。检索特定设备信息的调用是从此对象检索获取的。

创建了 WURFL Manager 对象,就可以查询 WURFL 以获取几个数据片段,如 清单 7 所示。

清单 7. 查询数据的 WURFL
// This line detects the visiting device by looking at its HTTP Request ($_SERVER) 
$requestingDevice = $wurflManager->getDeviceForHttpRequest($_SERVER);?> <html> <body> <ul> <li>ID: <?php echo $requestingDevice->id; ?> </li> <li>Brand Name: <?php echo $requestingDevice->getCapability("brand_name"); ?> </li> <li>Model Name: <?php echo $requestingDevice->getCapability("model_name"); ?> </li> <li>Resolution Width: <?php echo $requestingDevice->getCapability("resolution_width"); ?> </li> <li>Resolution Height: <?php echo $requestingDevice->getCapability("resolution_height"); ?> </li> <li>PDF Support: <?php echo $requestingDevice->getCapability("pdf_support"); ?> </li> <li>Flash Support: <?php echo $requestingDevice->getCapability("full_flash_support"); ?> </li> </ul> </body> 
</html>

当我从 iPhone 4 上加载此页面时,我看到了该设备的 ID,其制造与模型信息、屏幕信息以及是否支持 PDF 和 Flash。图 1 显示了加载结果。

图 1. iPhone 4 示例代码的结果
图像显示 iPhone 4 中的浏览器结果

从该示例,您可以看到为设备检索一个功能值,就和使用适当的功能名称调用 getCapability 方法一样简单。

结束语

从这篇文章中,您可以看到在您的移动网站或应用程序中使用 WURFL 有许多好处。简单便捷地收集有关给定设备的信息,而非投入大量时间编写额外的代码来获取无法得到的数据,是目前为止这个强大的 DDR 最吸引人的部分。

本系列第 2 部分将深入探讨 WURFL PHP API,并提供如何将其使用到您的移动 PHP 开发中的示例。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亿愿网站各类文件自动全部下载

亿愿网站各类文件自动全部下载(yywebsitedownall)-简介 ---席卷网站的龙卷风&#xff0c;一网打尽各类网站的各种类型文件&#xff01;---不留死角的网站"爬虫"&#xff01;兼容绝大部分高新技术制作的网站!---万能下载器&#xff01;多线程,多文件,智能识别文件名的…

记录--如何搭建自己的网站(阿里云)--(一)

记录–如何搭建自己的网站&#xff08;阿里云&#xff09;&#xff08;一&#xff09; 在网上看了好多帖子&#xff0c;恕我理解能力有限&#xff0c;只看个半懂&#xff0c;自己鼓捣了好久才弄出来&#xff0c;所以记录一下自己的心路历程&#xff0c;也方便以后查阅。 第一…

Java实战项目之精品课程网站【源码+课后指导】_Java毕业设计/计算机毕业设计

可以用来做毕业设计的Java实战项目又双叒叕来啦&#xff01;快来学习吧~Java实战项目之精品课程网站【源码课后指导】_Java毕业设计/计算机毕业设计https://www.bilibili.com/video/BV1dq4y1h7Z2 Java多态性&#xff1a;Java什么是多态&#xff1f; 态性是面向对象编程的又一个…

【源码+项目部署】Java课程设计_精品课程网站_Java毕业设计_Java毕设项目_Java课设项目_Java实战项目_Java开源项目_计算机毕业设计

小伙伴们的课程设计应该都做的差不多了吧&#xff0c;还没搞定的小伙伴要抓紧时间了喔~ 本篇为大家带来的Java开源项目是精品课程网站&#xff01;快来学习吧~【源码项目部署】Java课程设计_精品课程网站_Java毕业设计_Java毕设项目_Java课设项目_Java实战项目_Java开源项目_计…

常用SEO查询工具

SEO工作者经常需要一些SEO工具的辅助&#xff0c;比如网站收录查询、PR查询等等&#xff0c;以便节省自己的时间&#xff0c;让SEO变得更加轻松。那么&#xff0c;常用的SEO工具都有哪些呢&#xff1f;月光博客今天就介绍一些常用的SEO工具网址&#xff0c;并将其进行分类&…

电子商务网站系统 iWebShop

iWebShop 是一款面向独立卖家的单用户开源网店系统&#xff0c;基于PHPMySQL框架开发&#xff0c;通过它可以迅速建立起一个B2C网上商城。 iWebShop基于iWebSI框架开发&#xff0c;在获得iWebSI技术平台库支持的条件下&#xff0c;iWebShop可以轻松满足用户量级百万至千万级的 …

开源企业网站建设系统 ASPCMS

2.0.0是上谷网络旗下aspcms开发的全新内核的开源企业建站系统&#xff0c;能够胜任企业多种建站需求&#xff0c;并且支持模版自定义、支持扩展插件等等&#xff0c;能够在短时间内完成企业建站。 ASPCMS 开源企业网站管理系统功能列表&#xff1a;1、支持一键生成html&#xf…

互联网网站的反爬虫策略浅析

因为搜索引擎的流行&#xff0c;网络爬虫已经成了很普及网络技术&#xff0c;除了专门做搜索的Google&#xff0c;Yahoo&#xff0c;微软&#xff0c;百度以外&#xff0c;几乎每个大型门户网站都有自己的搜索引擎&#xff0c;大大小小叫得出来名字得就几十种&#xff0c;还有各…

Awesome项目搜索网站

简介 最近突发奇想开发了一个Awesome项目搜索网站&#xff0c;整个网站看起来样子长这样。 为什么要开发一个这个呢&#xff1f;因为Github上有很多Awesome类型的项目&#xff0c;其实就是针对某一种类型的项目做一个聚合&#xff0c;然后使用markdown展示出来。但是感觉这样的…

网站搭建与部署(一)——云服务器使用

一、 购买云服务器 网上各种云服务器&#xff0c;看阿里云有免费试用版&#xff0c;就选择了阿里云。 二、 连接云服务器&#xff0c;这里有两种连接方式&#xff1a;Workbench远程连接和通过桌面连接。 1、 Workbench远程连接 不知道密码的可以选择重置密码 2、 桌面连接&a…

网站搭建与部署(二)——Nginx部署服务与代理

这里我用的后端语言是node.js&#xff0c;所以需要先安装node.js、mysql以及数据库工具Navicat。重点是Nginx的使用。 一、安装Nginx。 1、Nginx官网下载&#xff0c;这里我选择的是windows版本。 2、解压之后&#xff0c;双击nginx.exe&#xff0c;控制台一闪而过&#xff0c…

解决关闭浏览器后再打开,访问网站仍然自动登陆的问题

情况描述&#xff1a; 今天被授权以管理员身份登录管理系统&#xff0c;录入一些信息&#xff0c;但因为Chrome设置的是保存Cookie&#xff0c;并且先登录了自己的账号&#xff0c;所以即便关掉浏览器再打开&#xff0c;仍然是以自己的账号自动登录&#xff0c;而页面的注销按…

matplotlib/pandas/BeautifulSoup/wordcloud等在前程无忧网站爬取、分析上的应用(代码)

文章详细分析内容发布于个人公众号。谢谢大家关注&#xff1a; ID: DataDreamInitiate 公众号名称&#xff1a;数据分析X小硕 此处仅放爬虫及分析代码。有问题可公众号或博客回复讨论&#xff0c;谢谢&#xff01; 以下为搜索页面信息抓取、信息初步清理、岗位详细信息抓取…

不能通过IP地址访问网站的解决方案

在服务器的IIS中添加网站&#xff0c;端口设为8081.然后通过IIS能够直接浏览网站。 但是在我电脑上访问网站:http://xxxx.xxxx.xxxx.xxx/index.aspx 以IP的形式始终访问不了网站。 原因&#xff1a;windows防火墙一般只开放了80端口。通过其他端口访问服务器是被拒绝的。 解…

IIS配置网站出现404

HTTP 404或Not Found错误信息是HTTP的其中一种“标准回应信息”&#xff08;HTTP状态码&#xff09;&#xff0c;此信息代表客户端在浏览网页时&#xff0c;服务器无法正常提供信息&#xff0c;或是服务器无法回应且不知原因。 一般这种错误首先想到的就是请求的文件不存在。但…

GitHub Action自动完成华工疫情打卡、网站自动签到

AutoAction简介 该github工程主要是为了解决疫情期间华工需要不断地申报自身健康而建立,工程中使用GitHub Action来实现每天自动打卡工作。准备工作 1.一个github账号 2.一个163邮箱账号&#xff1a;用于发送签到成功邮件&#xff0c;推荐添加&#xff0c;为了方便验证是否签…

Latex 相关网站

公式王 在线进行公式图片识别&#xff0c;转换为 Latex 语法。 网址为 https://gongshi.wang/

B2C电商平台如何做SEO优化以提高流量?

B2C电子商城建设随着电商行业的发展而快速被搭建&#xff0c;B2C商城系统网站对于流量的需求也是很大的&#xff0c;有了流量才能去进行转化&#xff0c;从而获得更多的客户&#xff0c;获取更多的市场份额。想要提高流量就要从自然搜索的优化技巧入手&#xff0c;只有掌握了优…

教你免费且快速地搭建个人网站

今日科技快讯 针对近日坊间流传的“我们天天在看你的微信”一说&#xff0c;微信团队今天发表声明重申三条用户隐私原则&#xff1a;1、微信不留存任何用户的聊天记录&#xff0c;聊天内容只存储在用户的手机、电脑等终端设备上&#xff1b;2、微信不会将用户的任何聊天内容用于…

直接从网站下载视频的方法

直接从网站下载视频的方法 很多时候浏览器插件搞不定的事情就要自己动动手嘛。 1. 没加密的网页 开发者工具里找太费眼睛了 最快捷的方法就是用 you-get 直接下载 这里需要先安装python&#xff0c;站里就有许多帖子&#xff0c;我就不赘述了 有了python之后&#xff0c;我们…