python-网页自动化(二)

news2024/11/13 9:07:08

获取元素属性

1. 获取属性

以百度首页的logo为例,获取logo相关属性

<img hidefocus="true" id="s_lg_img" class="index-logo-src"
src="//www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" width="270"
height="129"
οnerrοr="this.src='//www.baidu.com/img/flexible/logo/pc/index.png';this.οnerrοr=nul
l;" usemap="#mp">

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'C:\\Users\\77653\\AppData\\Local\\Microsoft\\WindowsApps\\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
logo = browser.find_element(By.CLASS_NAME, 'index-logo-src')
print(logo)
print(logo.get_attribute('src'))
# 关闭浏览器
browser.quit()
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
hot = browser.find_element(By.CSS_SELECTOR, '#hotsearch-content-wrapper > li:nth-child(1) > a')
print(hot.text)
print(hot.get_attribute('href'))
# 关闭浏览器
browser.quit()

#清除python

input.clear()

#回车查询

input.submit()

运行后输出:

<selenium.webdriver.remote.webelement.WebElement
(session="d4c9ee59e1b2f2bfdf4b11a2e699f063", element="e71cceb6-7cd8-4002-a078-
45b5aa497c94")>
https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png

2. 获取文本

以热榜为例,获取热榜文本和链接

<a class="title-content tag-width c-link c-font-medium c-line-clamp1"
href="https://www.baidu.com/s?
cl=3&amp;tn=baidutop10&amp;fr=top1000&amp;wd=%E5%8C%97%E4%BA%AC%E5%86%AC%E5%A5%A5%E
9%97%AD%E5%B9%95+2026%E7%B1%B3%E5%85%B0%E8%A7%81&amp;rsv_idx=2&amp;rsv_dl=fyb_n_hom
epage&amp;sa=fyb_n_homepage&amp;hisfilter=1" target="_blank"><span class="title-
content-index c-index-single c-index-single-hot1">1</span><span class="title-
content-title">北京冬奥闭幕 2026米兰见</span></a>

获取热榜的文本,用的是text 属性,直接调用即可

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'C:\\Users\\77653\\AppData\\Local\\Microsoft\\WindowsApps\\chromedriver.exe')

# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
hot = browser.find_element(By.CSS_SELECTOR, '#hotsearch-content-wrapper > li:nth-child(1) > a')
print(hot.text)
print(hot.get_attribute('href'))
# 关闭浏览器
browser.quit()

1各地贯彻十九届六中全会精神纪实
https://www.baidu.com/s?
cl=3&tn=baidutop10&fr=top1000&wd=%E5%90%84%E5%9C%B0%E8%B4%AF%E5%BD%BB%E5%8D%81%E4%B
9%9D%E5%B1%8A%E5%85%AD%E4%B8%AD%E5%85%A8%E4%BC%9A%E7%B2%BE%E7%A5%9E%E7%BA%AA%E5%AE%
9E&rsv_idx=2&rsv_dl=fyb_n_homepage&sa=fyb_n_homepage&hisfilter=1

3. 获取其他属性

除了属性和文本值外,还有id、位置、标签名和大小等属性。

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
logo = browser.find_element(By.CLASS_NAME, 'index-logo-src')
print(logo.id)
print(logo.location)
print(logo.tag_name)
print(logo.size)
# 关闭浏览器
browser.quit()

输出:

ffec5900-4bd5-4162-a127-e970bc3e85a6
{'x': 490, 'y': 151}
img
{'height': 129, 'width': 270}

页面交互操作

页面交互就是在浏览器的各种操作,比如上面演示过的输入文本、点击链接等等,还有像清除文本、回车确认、单选框与多选框选中等。

1. 输入文本

其实,在之前的小节中我们有用过此操作。 send_keys()

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
browser.find_element(By.CLASS_NAME, 's_ipt').send_keys('python')
time.sleep(2)
# 关闭浏览器
browser.quit()

2. 点击

同样,我们也用过这个点击操作。click()

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
browser.find_element(By.LINK_TEXT, '新闻').click()
time.sleep(2)
# 关闭浏览器
browser.quit()

3. 清除文本

既然有输入,这里也就有清除文本啦。 clear()

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
# 定位搜索框
input = browser.find_element(By.CLASS_NAME, 's_ipt')
# 输入python
input.send_keys('python')
time.sleep(2)
# 清除python
input.clear()
time.sleep(2)
# 关闭浏览器
browser.quit()

4. 回车确认

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问百度首页
browser.get(r'https://www.baidu.com/')
time.sleep(2)
# 定位搜索框
input = browser.find_element(By.CLASS_NAME, 's_ipt')
# 输入python
input.send_keys('python')
time.sleep(2)
# 回车查询
input.submit()
time.sleep(5)
# 关闭浏览器
browser.quit()

5. 单选

单选比较好操作,先定位需要单选的某个元素,然后点击一下即可。

6. 多选

多选好像也比较容易,依次定位需要选择的元素,点击即可。

7. 下拉框

下拉框的操作相对复杂一些,需要用到 Select 模块。
先导入该类:

from selenium.webdriver.support.select import Select

se1ect 模块中有以下定位方法

 '''1、三种选择某一选项项的方法'''
select_by_index()                         # 通过索引定位;注意:index索引是从“0”开始。
select_by_value()                         # 通过value值定位,value标签的属性值。
select_by_visible_text()                 # 通过文本值定位,即显示在下拉框的值。
'''2、三种返回options信息的方法'''
options # 返回select元素所有的options
all_selected_options                         # 返回select元素中所有已选中的选项
first_selected_options                         # 返回select元素中选中的第一个选项
'''3、四种取消选中项的方法'''
deselect_all                                         # 取消全部的已选择项

 deselect by_index                                # 取消已选中的索引项

deselect_by_value                                 # 取消已选中的value值
deselect_by_visible_text                         # 取消已选中的文本值

我们来进行演示一波,由于暂时没找到合适的网页,我们自己动手写一个简单的网页本地测试,在 E:\ 下新建一个文本文档,输入以下内容:

<html>
<body align="center">
    <form>
        <select name="训练营">
            <option value="1">第一期</option>
            <option value="2" selected="">第二期</option>
            <option value="3">第三期</option>
            <option value="4">第四期</option>
        </select>
    </form>
</body>
</html>

保存后,把文件名修改为:训练营.html。
现在来演示下拉框的不同选择的方式

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select
s = Service(r'C:\Users\77653\AppData\Local\Microsoft\WindowsApps\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 访问本地网页
browser.get(r'file:///E:/训练营.html')
time.sleep(2)
# 根据索引选择
Select(browser.find_element(By.NAME, "训练营")).select_by_index("2")
time.sleep(2)
# 根据value值选择
Select(browser.find_element(By.NAME, "训练营")).select_by_value("4")
time.sleep(2)
# 根据文本值选择
Select(browser.find_element(By.NAME, "训练营")).select_by_visible_text("第二期")
time.sleep(2)
# 关闭浏览器
browser.quit()

显示效果如下:

多窗口切换

比如同一个页面的不同子页面的节点元素获取操作,不同选项卡之间的切换以及不同浏览器窗口之间的切换操作等等。

1. Frame切换

Selenium 打开一个页面之后,默认是在父页面进行操作,此时如果这个页面还有子页面,想要获取子页面的节点元素信息则需要切换到子页面进行擦走,这时候 switch_to.frame() 就来了。如果想回到父页面,用 switch_to.parent_frame() 即可。

2. 选项卡切换

我们在访问网页的时候会打开很多个页面,在 Selenium 中提供了一些方法方便我们对这些页面进行
操作。

current_window_handle :获取当前窗口的句柄。
window_handles :返回当前浏览器的所有窗口的句柄。
switch_to_window() :用于切换到对应的窗口。

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 打开百度
browser.get(r'https://www.baidu.com')
# 新建一个选项卡
browser.execute_script('window.open()')
print(browser.window_handles)
# 跳转到第二个选项卡并打开知乎
browser.switch_to.window(browser.window_handles[1])
browser.get(r'https://www.zhihu.com')
# 回到第一个选项卡并打开淘宝(原来的百度页面改为了淘宝)
time.sleep(2)
browser.switch_to.window(browser.window_handles[0])
browser.get(r'https://www.taobao.com')
# 关闭浏览器
browser.quit()

 模拟鼠标操作

既然是模拟浏览器操作,自然也就需要能模拟鼠标的一些操作了,这里需要导入 ActionChains 类。

from selenium.webdriver.common.action chains import Actionchains

1. 左键

这个其实就是页面交互操作中的点击 click() 操作。

2. 右键

使用函数 context_click() 操作。

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 打开百度
browser.get(r'https://www.baidu.com')
# 定位到要右击的元素,这里选的新闻链接
right_click = browser.find_element(By.LINK_TEXT, '新闻')
# 执行鼠标右键操作
ActionChains(browser).context_click(right_click).perform()
time.sleep(2)
# 关闭浏览器
browser.quit()

在上述操作中

Actionchains(browser):调用Actionchains()类,并将浏览器驱动 browser 作为参数传入

context_c1ick(right_click):模拟鼠标双击,需要传入指定元素定位作为参数

perform():执行 Actionchains()中储存的所有操作,可以看做是执行之前一系列的操作

3. 双击

使用函数 double_click() 操作。

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 打开百度
browser.get(r'https://www.baidu.com')
# 定位到要双击的元素
double_click = browser.find_element(By.CSS_SELECTOR, '#bottom_layer > div > p:nth-
child(8) > span')
# 双击
ActionChains(browser).double_click(double_click).perform()
time.sleep(15)
# 关闭浏览器
browser.quit()

通过双击选择中对应的文字,效果如下:

4. 拖拽

drag_and_drop(source,target) 意思就是拖拽操作嘛,开始位置和结束位置需要被指定,这个常用
于滑块类验证码的操作之类。
我们以菜鸟教程的一个案例来进行演示

菜鸟教程在线编辑器icon-default.png?t=O83Ahttps://www.runoob.com/try/try.php?filename=jqueryui-api-droppable

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 打开百度
browser.get(r'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
time.sleep(2)
# 切换至子页面
browser.switch_to.frame('iframeResult')
# 开始位置
source = browser.find_element(By.CSS_SELECTOR, "#draggable")
# 结束位置
target = browser.find_element(By.CSS_SELECTOR, "#droppable")
# 执行元素的拖放操作
actions = ActionChains(browser)
actions.drag_and_drop(source, target)
actions.perform()
# 拖拽
time.sleep(15)
# 关闭浏览器
browser.quit()

拖拽到目标位置后,弹出如下界面:

5. 悬停

使用函数 move_to_element() 操作。

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 打开百度
browser.get(r'https://www.baidu.com')
time.sleep(2)
# 定位悬停的位置
move = browser.find_element(By.CSS_SELECTOR, "#form > span.bg.s_ipt_wr.new-
pmd.quickdelete-wrap > span.soutu-btn")
# 悬停操作
ActionChains(browser).move_to_element(move).perform()
time.sleep(5)
# 关闭浏览器
browser.quit()

运行后效果如下:

模拟键盘操作

selenium 中的 Keys() 类提供了大部分的键盘操作方法,通过 send_keys() 方法来模拟键盘上的按
键。
引入 Keys 类

from selenium.webdriver.common.keys import Keys

常见的键盘操作

 

 实例操作演示:
定位需要操作的元素,然后操作即可!

import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
s = Service(r'D:\driver\chromedriver.exe')
# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=s)
# 打开百度
browser.get(r'https://www.baidu.com')
time.sleep(2)
# 定位搜索框
input = browser.find_element(By.CLASS_NAME, 's_ipt')
# 输入python
input.send_keys('python')
time.sleep(2)
# 回车
input.send_keys(Keys.ENTER)
time.sleep(5)
# 关闭浏览器
browser.quit()

课程总结

本节课学习了获取元素属性,多窗口切换,页面交互操作和模拟鼠标、键盘操作这些基本的功能,为每一个功能都编写了一个案例,先模仿再修改,多写多练,加深记忆。

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

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

相关文章

微服务-nacos

nacos-注册中心 启动 服务注册到nacos

【MIT 6.5840/6.824】In Search of an Understandable Consensus Algorithm 学习笔记

In Search of an Understandable Consensus Algorithm 1 Introduction2 Replicated state machines3 What’s wrong with Paxos?4 Designing for understandability5 The Raft consensus algorithm5.1 Raft basics5.2 Leader election5.3 Log replication5.4 Safety5.4.1 Elec…

知识付费最新版知识付费做的最好的平台,网创资源知识付费 知识付费网站搭建,搭建知识付费APP平台教学:在线教育系统源码。

目录 前言&#xff1a; 一、知识付费平台特点 二、知识付费平台功能 三、 知识付费小程序 前言&#xff1a; 知识付费小程序是一种在线学习平台&#xff0c;用户可以通过该小程序以一定的费用获取专业知识和技能。这些知识和技能可以来自行业专家、教育机构或个人创作者。知…

Docker 容器技术:简化 MySQL 主从复制部署与优化

文章目录 前言一、为什么基于Docker搭建&#xff1f;二、利用Docker搭建主从服务器2.1 配置Master&#xff08;主&#xff09;2.2 配置Slave&#xff08;从&#xff09;2.3 链接Master&#xff08;主&#xff09;和Slave&#xff08;从&#xff09;2.4 测试主从复制 三、常见问…

面试官:你有写过自定义指令吗?自定义指令的应用场景有哪些?

一、什么是指令 开始之前我们先学习一下指令系统这个词 指令系统是计算机硬件的语言系统&#xff0c;也叫机器语言&#xff0c;它是系统程序员看到的计算机的主要属性。因此指令系统表征了计算机的基本功能决定了机器所要求的能力 在vue中提供了一套为数据驱动视图更为方便的…

VMWARE VCENTER6.7 VCSA通过Web5480进行版本升级

VCENTER当前版本如下图 操作前先给VCENTER打一个快照&#xff0c;出问题可以立即回退 1、先下载VCSA镜像&#xff0c;并将VCSA镜像上传至DataStore中&#xff1b; 2、选中VCSA虚拟机&#xff0c;编辑配置 3、挂载新上传的VCSA镜像&#xff0c;一定要勾选“已连接”和“打开电源…

自定义string类

#include <iostream> #include <string> int main() { std::string str "Hello, World!"; // 使用 c_str() 将 std::string 转换为 C 风格字符串&#xff0c;并传递给 printf printf("The string is: %s\n", str.c_str()); // 尝试修改…

网络层 V(IPv6)【★★★★★★】

一、IPv6 的特点 IP 是互联网的核心协议。现在使用的 IP&#xff08;即 IPv4 ) 是在 20 世纪 70 年代末期设计的。互联网经过几十年的飞速发展&#xff0c;到 2011 年 2 月&#xff0c;IPv4 的地址已经耗尽&#xff0c; ISP 已经不能再申请到新的 IP 地址块了。我国在 2014 年…

全能与专精:探索未来AI模型的发展趋势与市场潜力

文章目录 每日一句正能量前言AI模型的全面评估和比较AI模型的专精化和可扩展性AI模型的合理使用和道德规范后记 每日一句正能量 一个人&#xff0c;如果没有经受过投资失败的痛楚&#xff0c;又怎么会看到绝望之后的海阔天空。很多时候&#xff0c;经历了人生中最艰难的事&…

告别繁琐切换,可道云teamOS让企业微信和钉钉无缝对接,爽到飞起

在当今快节奏的工作环境中&#xff0c;企业对于高效办公工具的需求日益增强。特别是企业微信和钉钉的普及&#xff0c;已成为许多企业日常沟通协作的基石。然而&#xff0c;传统企业网盘与这些平台的割裂&#xff0c;常常让工作流程变得繁琐。 幸运的是&#xff0c;teamOS的出…

vs2019编译opencv+contribute+gpu

1、提前准备 vs2019、opencv4.4.0、opencv-contribute4.4.0、CUDA Toolkit 11.8&#xff08;不能高于自己电脑的CUDA版本&#xff09;、CUDNN8.9.6 ps&#xff1a;先提前准备环境 1&#xff09;cmd中查看&#xff1a;nvidia-smi查看自己的显卡信息&#xff0c;不存在下述信息…

文本匹配任务(下)

文本匹配任务 1.文本匹配-深度学习1.1表示型1.1.1训练方式一1.1.2训练方式二&#xff08;Triplet Loss&#xff09; 1.2交互型1.3交互型和表示型对比 2.对比学习2.1图像中2.2NLP中 3.真实场景-海量向量查找3.1CD树3.1.1空间切割3.1.2Annoy 1.文本匹配-深度学习 简介&#xff1…

EasyExcel 文件导出 - 合并某些列值相同的行

文章目录 EasyExcel 文件导出 - 合并某些列值相同的行最终效果实现思路创建单元格合并的策略类使用 EasyExcel 文件导出 - 合并某些列值相同的行 在数据处理与文件导出的过程中&#xff0c;我们常常会遇到各种特定的需求。今天&#xff0c;我们就来探讨一下使用 EasyExcel 进行…

VsCode 联想路径配置

问题&#xff1a;举一个例子&#xff0c;引入文件 import store from ‘./store’&#xff0c;在输入 ./st 后会提示store。 配置路径别名后 webpack: {// 配置别名alias: {// 使用 表示 src 文件所在路径: path.resolve(__dirname, src)}}项目配置路径后输入 import store f…

JVM面试真题总结(一)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ Java主要是解释执行还是编译执行?请说明理由 Java既是解释执行的…

828华为云征文|部署私有云和文档管理系统 Kodcloud

828华为云征文&#xff5c;部署私有云和文档管理系统 Kodcloud 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 产品优势1.3 对比Flexus L实例和ECS 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Kodcloud3.1 Kodcloud 介绍3.2 Docker 环境…

Google数字车钥匙:引领汽车互动新纪元

在科技的浪潮中&#xff0c;Digital Car Key正以一种全新的姿态重塑我们与汽车的互动。告别传统的钥匙束缚&#xff0c;只需轻触手机应用&#xff0c;即可轻松掌控汽车。这一创新解决方案不仅大幅提升了安全性&#xff0c;更带来了前所未有的便捷&#xff0c;无论是城市通勤还是…

SSM校园兼职网站—计算机毕业设计源码25557

摘 要 当今人类社会已经进入信息全球化和全球信息化、网络化的高速发展阶段。丰富的网络信息已经成为人们工作、生活、学习中不可缺少的一部分。人们正在逐步适应和习惯于网上贸易、网上购物、网上支付、网上服务和网上娱乐等活动&#xff0c;人类的许多社会活动正在向网络化发…

Kafka【九】如何实现数据的幂等性操作

为了解决Kafka传输数据时&#xff0c;所产生的数据重复和乱序问题&#xff0c;Kafka引入了幂等性操作&#xff0c;所谓的幂等性&#xff0c;就是Producer同样的一条数据&#xff0c;无论向Kafka发送多少次&#xff0c;kafka都只会存储一条。注意&#xff0c;这里的同样的一条数…

C++ 在给定斜率的线上找到给定距离处的点(Find points at a given distance on a line of given slope)

给定二维点 p(x 0 , y 0 )的坐标。找到距离该点 L 的点&#xff0c;使得连接这些点所形成的线的斜率为M。 例子&#xff1a; 输入&#xff1a; p (2, 1) L sqrt(2) M 1 输出&#xff1a;3, 2 1, 0 解释&#xff1a; 与源的距离为 sqrt(2) &#x…