Python - Python Selenium 套件使用参考笔记

Python - Python Selenium 套件使用参考笔记

参考资料

说明

当初会写这篇参考笔记,主要是因为, Selenium-Python 的中文文件,看起来应该是大陆人翻译的,只有简体中文,没有繁体中文的版本,所以我就自己整理了繁体中文的版本,再把里面的大陆用语转换成台湾用语(先说我不是专业的,用词错误请不要喷我w),增加或删减一些文字,以方便肉眼阅读XD。

特此撰写本篇文章作为纪录文件,用以方便後续有需要的时候,可以快速的重复查阅,虽然後面比较没有什麽机会再用到,但也算是一个还不错的经验。

安装Selenium

指令如下:

pip3 install selenium

下载与安装 Chrome Driver

请前往下方连结,下载对应版本的 Chrome Driver,并将压缩档内的chromedriver.exe解压缩到指定的工作目录。
ChromeDriver - WebDriver for Chrome

使用 Selenium 开启 Chrome 浏览器

开启 Chrome 浏览器,并前往 Google 搜寻页面,然後再关闭浏览器,程序码如下:

from selenium import webdriver
driver = webdriver.Chrome('chromedriver.exe')
driver.get('https://www.google.com')
driver.close()

使用 Selenium 查找元素定位

通过 Class name 定位元素

当你通过 class name 查找元素时可使用这个。在该策略下,页面中第一个匹配该 class 属性的元素会被匹配并返回。如果找不到任何元素,则会抛出 NoSuchElementException 异常。

driver.find_element_by_class_name('class name')

通过CSS选择器查找元素

当你通过CSS选择器查找元素时可以使用这个。在该策略下,页面中第一个匹配该 CSS 选择器的元素会被匹配并返回。如果找不到任何元素,则会抛出 NoSuchElementException 异常。

driver.find_element_by_css_selector('css selector')

通过 ID 查找元素

当你知道一个元素的 id 时,你可以使用本方法。在该策略下,页面中第一个符合该 id 的元素会被匹配并返回。如果找不到任何元素,会抛出 NoSuchElementException 异常。

driver.find_element_by_id('id')

通过连结文字查找元素

当你知道在一个连结标签中使用的文字时可使用这个。在该策略下,页面中第一个匹配连结文字的标签会被匹配并返回。如果找不到任何元素,则会抛出 NoSuchElementException 异常。

driver.find_element_by_link_text('link text')

也可以只用连结的部分文字定位元素:

driver.find_element_by_partial_link_text('partial link text')

通过 Name 查找元素

当你知道一个元素的 name 时,你可以使用本方法。在该策略下,页面中第一个该 name 元素会被匹配并返回。如果找不到任何元素,会抛出 NoSuchElementException 异常。

driver.find_element_by_name('name')

通过标签名 tag 查找元素

当你通过标签名 tag 查找元素时可使用这个。在该策略下,页面中第一个匹配该标签名的元素 会被匹配并返回。如果找不到任何元素,会抛出 NoSuchElementException 异常。

driver.find_element_by_tag_name('tag')

通过XPath查找元素

XPath是XML文档中查找结点的语法。因为HTML文档也可以被转换成XML(XHTML)文档, Selenium的用户可以利用这种强大的语言在web应用中查找元素。 XPath扩展了(当然也支持)这种通过id或name属性获取元素的简单方式,同时也开辟了各种新的可能性, 例如获取页面上的第三个复选框。

使用XPath的主要原因之一就是当你想获取一个既没有id属性也没有name属性的元素时, 你可以通过XPath使用元素的绝对位置来获取他(这是不推荐的),或相对於有一个id或name属性的元素(理论上的父元素)的来获取你想要的元素。 XPath定位器也可以通过非id和name属性查找元素。

绝对的XPath是所有元素都从根元素的位置(HTML)开始定位,只要应用中有轻微的调整,会就导致你的定位失败。但是通过就近的包含id或者name属性的元素出发定位你的元素,这样相对关系就很靠谱, 因为这种位置关系很少改变,所以可以使你的测试更加强大。

driver.find_element_by_xpath('//*[@id="lst-ib"]')

使用 Selenium 操作网页元素

开启 Chrome 浏览器,并前往 Google 搜寻页面,然後搜寻"你好"并按下 Enter,程序码如下:

from selenium import webdriver
driver = webdriver.Chrome('chromedriver.exe')
driver.get('https://www.google.com')
q  = driver.find_element_by_name('q')

q.send_keys('你好')

from selenium.webdriver.common.keys import Keys
q.send_keys(Keys.RETURN)

开启 Chrome 浏览器,并前往 Google 搜寻页面,然後点击登入按钮,程序码如下:

from selenium import webdriver
driver = webdriver.Chrome('chromedriver.exe')
driver.get('https://www.google.com')

login = driver.find_element_by_link_text('登入')

login.click()

使用 Selenium 操作 frame 标签中的元素

很多人在用selenium定位页面元素的时候会遇到定位不到的问题,明明元素就在那儿,就是定位不到,这种情况很有可能是frame 在搞鬼(可能原因之一),可以去仔细看看你网页的DOM树!

frame标签有framesetframeiframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,selenium有一组方法对frame进行操作:

driver.switch_to.frame(reference)  # 切到指定frame,可用id或name(str)、index(int)、元素(WebElement)定位
driver.switch_to.parent_frame()  # 切到父级frame,如果已是主文档,则无效果
driver.switch_to.default_content()  # 切到主文档,DOM树最开始的<html>标签

1. 怎麽切到frame中(switch_to.frame())

selenium提供了switch_to.frame()方法来切换frame

switch_to.frame(reference)

reference是传入的参数,用来定位frame,可以传入id、name、index以及selenium的WebElement对象,假设有如下HTML代码 index.html:

<html lang="en">
<head>
    <title>FrameTest</title>
</head>
<body>
<iframe src="a.html" id="frame1" name="myframe"></iframe>
</body>
</html>

想要定位其中的iframe并切进去,可以通过如下代码:

from selenium import webdriver
driver = webdriver.Firefox()
driver.switch_to.frame(0)  # 1.用frame的index来定位,第一个是0
# driver.switch_to.frame("frame1")  # 2.用id来定位
# driver.switch_to.frame("myframe")  # 3.用name来定位
# driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))  # 4.用WebElement对象来定位

通常采用id和name就能够解决绝大多数问题。但有时候frame并无这两项属性,则可以用index和WebElement来定位:

  • index从0开始,传入整型参数即判定为用index定位,传入str参数则判定为用id/name定位
  • WebElement对象,即用find_element系列方法所取得的对象,我们可以用tag_name、xpath等来定位frame对象

举个例子:

<iframe src="myframetest.html" />

用xpath定位,传入 WebElement 物件:

driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(@src,'myframe')]"))

2. 从frame中切回主文档(switch_to.default_content())

切到frame中之後,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档。

driver.switch_to.default_content()

3. 嵌套frame的操作(switch_to.parent_frame())

有时候我们会遇到嵌套的frame,如下:

<html>
	<iframe id="frame1">
		<iframe id="frame2" / >
	</iframe>
</html>
  1. 从主文档切到frame2,一层层切进去
driver.switch_to.frame("frame1")  # 先切到frame1
driver.switch_to.frame("frame2")  # 再切到frame2
  1. 从frame2再切回frame1,这里selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。
driver.switch_to.parent_frame()  # 如果目前已是主文档,则无效果

有了parent_frame()这个相当於後退的方法,我们可以随意切换不同的frame,随意的跳来跳去了。

所以只要善用以下三个方法,遇到frame分分钟搞定:

driver.switch_to.frame(reference)
driver.switch_to.parent_frame()
driver.switch_to.default_content()

使用 Selenium 滚动网页卷轴(scrollBar)

参考:Python Selenium控制网页滚动条缓慢滚动

通过driver.execute()执行js代码,达到目的。

driver.execute_script('window.scrollBy(0,1000)')

scrollBy(x,y)中,x为必须参数,表示向右滚动的像素值;y也为必须参数,表示向下滚动的像素值

driver.execute_script('window.scrollTo(0,1000)')

scrollTo(x,y) 中,x为必要参数,表示要在窗口文档显示区左上角显示的文档的x坐标;y也为必要参数,表示要在窗口文档显示区左上角显示的文档的y坐标

卷轴长度获取

参考:.body.scrollHeight doesn't work in Firefox

可以在 Chrome 的监控视窗的Console 下指令取得。
两个指令皆可使用,但在某些网站(如:Youtube)这两个指令,可能会有其中一个失效。

document.body.scrollHeight
document.documentElement.scrollHeight

selenium 卷轴拉到底:

方法一:

driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')

方法二:

driver.execute_script('window.scrollTo(0,document.documentElement.scrollHeight)')

<<:  捉鳖神技 - 让USB传输见光死的方法

>>:  Day 08. Zabbix 设定 SNMP 监控 Synology NAS DS920+

SystemC: 月球转运站

创世神创造了世界,还觉得不够,又做了一颗月球。 过了两天觉得地球不够圆,决定把存在月球的 pi拿回来...

完赛心得

首先很感谢it铁人赛给予我这个机会,让我做到平时连想不会想到的事。因为对於我而言,实在是没什麽能够说...

Day2 - Shioaji套件安装&相关问题

tags: 2021永丰金铁人赛 套件安装 要使用Shioaji套件,首先当然是要先安装起来,进入官...

[Day 7] 阿嬷都看得懂的文字标签与语意化标签

阿嬷都看得懂的文字标签与语意化标签 昨天我们开始写第一支 .html 程序了,不过网页看起来还是太朴...

Day-11 priority queue

Priority queue Priority queue和queue一样也有两种形式 : max ...