上一篇中,只是简单地一带而过的说了一些驱动浏览器,这一篇继续说说驱动浏览器,然后再说一说元素定位的方法。
完成环境的安装并测试之后,我们对Selenium有了一定的了解了,接下来我们继续驱动浏览器做一些基本操作:
窗口尺寸设置、网页截图、刷新、前进和后退
在测试过程中,我们可能会要求打开浏览器的窗口处于最大化或者设置为某一特定尺寸的大小,所以我们使用selenium驱动浏览器时设定窗口大小
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2019-11-26 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium-驱动浏览器和元素定位大法 ''' # 3.导入模块 import time from selenium import webdriver driver = webdriver.Chrome() # 启动chrome def get_size(driver): """ 获取窗口尺寸并打印 """ size = driver.get_window_size() # 获取窗口尺寸 print(size) # 打印窗口尺寸 time.sleep(3) # 暂停3秒 driver.get("https://www.google.com") # 打开网页 get_size(driver) driver.set_window_size(800,600) # 设置窗口尺寸为800*600 get_size(driver) driver.minimize_window() # 窗口最小化,窗口尺寸未发生变化 get_size(driver) driver.maximize_window() # 窗口最大化 get_size(driver) driver.quit() # 停止进程
在完成打开网页时,我们对网页内容进行保存的方式的一种就是进行网页截图,webdriver中就提供了截图的选择
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2019-11-26 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium-驱动浏览器和元素定位大法 ''' # 3.导入模块 from selenium import webdriver driver = webdriver.Chrome() # 创建driver对象,启动chrome driver.get("https://www.google.com") # 打开网页 driver.get_screenshot_as_file("D:\\screenshot.png") # 截图 driver.quit() # 停止进程
如同在浏览器中进行常规按钮操作,依次打开多个网页后,需要对网页刷新,返回、前进
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2019-11-26 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium-驱动浏览器和元素定位大法 ''' # 3.导入模块 import time from selenium import webdriver driver = webdriver.Chrome() # 打开两个网页 driver.get("https://www.baidu.com") time.sleep(3) driver.get("https://www.google.com") time.sleep(3) # 进行后退、前进操作 driver.back() # 后退 time.sleep(3) driver.forward() # 前进 time.sleep(3) # 对网页进行刷新 driver.refresh() driver.quit()
一些基本操作就完成了,接下来我们就可以做更多~
webdriver 提供了八种元素定位方法:
id name class name tag name link text partial link text xpath css selector
在 Python 语言中对应的定位方法如下:
find_element_by_id() find_element_by_name() find_element_by_class_name() find_element_by_tag_name() find_element_by_link_text() find_element_by_partial_link_text() find_element_by_xpath() find_element_by_css_selector()
下面我们就逐一的来看这些定位方法的使用。在此之前,我们拷取百度首页的前端代码,以定位页面上的元素为例进行讲解。
<html> <head> <body> <script> <div id="wrapper" style="display: block;"> <div id="debug" style="display:block;position:.."> <script> <div id="head" class="s_down"> <div class="head_wrapper"> <div class="s_form"> <div class="s_form_wrapper"> <div id="lg"> <a id="result_logo" οnmοusedοwn="return .." href="/"> <form id="form" class="fm" action="/s" name="f"> <input type="hidden" value="utf-8" name="ie"> <input type="hidden" value="8" name="f"> <input type="hidden" value="1" name="rsv_bp"> <input type="hidden" value="1" name="rsv_idx"> <input type="hidden" value="" name="ch"> <input type="hidden" value="02.." name="tn"> <input type="hidden" value="" name="bar"> <span class="bg s_ipt_wr"> <input id="kw" class="s_ipt" autocomplete="off" maxlength="100" value="" name="wd"> </span> <span class="bg s_btn_wr"> <input id="su" class="bg s_btn" type="submit" value="百度一下"> </span> .... </body> </html>hello
注意这段代码并非百度首页的页面源代码,而是通过前端工具查看所得到页面代码与结构。那么这样的 HTML 结构有如下特征。
(1)它们由标签对组成:
<html></html> <body></body> <div></div> <form></form>
那么 html、div 就是标签的标签名。
(2)标签各种属性属性:
<div id="head" class="s_down"> <from class="well"> <input id="kw" name="wd" class="s_ipt">
就像人一样也会有各种属性,身份证号(id)、姓名(name)、职业(class)等。
(3)标签对之间可以有文本数据。
<a>新闻</a> <a>hao123</a> <a>地图</a>
(4)标签有由层级关系
<html> <body> </body> </html> <div> <from> <input /> </from> <div>
对于上面结构,如果把 input 看作是子标签,那么 form 就是它的父标签。
理解了上面这些特性是学习定位方法的基础。我们以百度输入框和百度搜索按钮为例来学习不同的定位方法,两个元素的代码如下。
…… <input id="kw" class="s_ipt" autocomplete="off" maxlength="100" value=""name="wd"> …… <input id="su" class="bg s_btn" type="submit" value="百度一下">
name 如果把页面上看元素看作一个人的话,如果我们想找一个人如何去找,那么这个人一定有其别于其它人的“属性”,比如他的身份证号一定和别人不一样,他的名字和别人不一样。那么我们就可以通过身证号和名字来找到一个人。那么 id 就可以看做是一个人的身
份号,当然这个 id 并不像我们现实中的身份证号有那么强的唯一性,如果在一个页面上发现有两个元素的 id="kw"也是不足为奇的,这个取决前端代码的规范程度。
对百度首页上的输入框与百度搜索按钮来说,定位方法如下:
find_element_by_id("kw") find_element_by_id("su") find_element_by_id()方法用于元素中 id 属性的定位。
name 的定位与 id 类似,每一个人都会有名字,那么 name 就可作是一个元素的名字。通过 name 定位输入框:
find_element_by_name("wd")
find_element_by_name()方法用于元素中 name 属性的定位,百度搜索按钮并没有提供 name 属性,那么我们就不能通过 name 去定位百度搜索按钮。
class 也是不少元素会有的一个属性,它的定位和 name 以及 id 类似,下面通过 class 去定位百度输入框和百度搜索按钮:
find_element_by_class_name("s_ipt") find_element_by_class_name("bg s_btn") find_element_by_class_name()方法用于元素中 class 属性的定位。
tag 定位取的是一个元素的标签名,通过标签名去定位单个元素的唯一性最底,因为在一个页面中有太多的元素标签为<div>和<input>了,所以很难通过标签名去区分不同的元素。
通过标签名定位百度首页上的输入框与百度搜索按钮:
find_element_by_tag_name("input") find_element_by_tag_name("input")
find_element_by_tag_name()方法通过元素的 tag name 来定位元素。通过上面的例子,我们并不能区别不同的元素,因为在一个页面上标签名相同很难以避免。
link 定位与前面介绍的几种定位方法有所不同,它专门用来定位本链接。百度输入框上面的几个文本链接的代码如下:
<a class="mnav" name="tj_trnews" href="http://news.baidu.com">新闻</a> <a class="mnav" name="tj_trhao123" href="http://www.hao123.com">hao123</a> <a class="mnav" name="tj_trmap" href="http://map.baidu.com">地图</a> <a class="mnav" name="tj_trvideo" href="http://v.baidu.com">视频</a> <a class="mnav" name="tj_trtieba" href="http://tieba.baidu.com">贴吧>
通过查看上面的代码,我们发现通过 name 属性定位是个不错的选择。不过我们这里为了要学习 link定位,通过 link 定位实现如下:
find_element_by_link_text("新闻") find_element_by_link_text("hao123") find_element_by_link_text("地图") find_element_by_link_text("视频") find_element_by_link_text("贴吧")
find_element_by_link_text()方法通过元素标签对之间的文本信息来定位元素。不过,需要强调的是Python 对于中文的支持并不好,如查 Python 在执行中文的地方出现在乱码,可以在中文件字符串的前面加个小“u”可以有效的避免乱码的问题,加 u 的作用是把中文字
符串转换中 unicode 编码,如:
find_element_by_link_text(u"新闻")
parial link 定位是对 link 定们的一个种补充,有些文本连接会比较长,这个时候我们可以取文本链接的有一部分定位,只要这一部分信息可以唯一的标识这个链接。
<a class="mnav" name="tj_lang" href="#">一个很长很长的文本链接</a>
通过 partial link 定位如下:
find_element_by_partial_link_text("一个很长的") find_element_by_partial_link_text("文本连接")
find_element_by_link_text()方法通过元素标签对之间的部分文本信息来定位元素。
selenium提供了多种方式进行定位元素:?find_element_by_*?
1 find_element_by_id 2 find_element_by_name 3 find_element_by_xpath 4 find_element_by_link_text 5 find_element_by_partial_link_text 6 find_element_by_tag_name 7 find_element_by_class_name 8 find_element_by_css_selector
当然也可以一次定位多个元素:?find_elements_by_*?
1 find_elements_by_name 2 find_elements_by_xpath 3 find_elements_by_link_text 4 find_elements_by_partial_link_text 5 find_elements_by_tag_name 6 find_elements_by_class_name 7 find_elements_by_css_selector
因为id是唯一的,所以一次定位多个元素是没有办法通过id进行定位的。
同样,可以通过?find_element?和??find_elements?,不过使用之前需要导入by类,?from?selenium.webdriver.common.by?import?By?。
# coding=utf-8🔥 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 # 2.注释:包括记录创建时间,创建人,项目名称。 ''' Created on 2019-11-26 @author: 北京-宏哥 QQ交流群:705269076 Project: python+ selenium-驱动浏览器和元素定位大法 ''' # 3.导入模块 import time from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() # 打开一个网页 driver.get("https://www.zhihu.com/") # 查找一个元素的方法 ele = driver.find_element_by_xpath( '//*[@id="root"]/div/div[2]/header/div/nav/a[2]') ele.click() # 点击已定位的元素 driver.back() # 退回 time.sleep(5) ele = driver.find_element( By.XPATH, '//*[@id="root"]/div/div[2]/header/div/nav/a[2]') # ID = "id" # XPATH = "xpath" # LINK_TEXT = "link text" # PARTIAL_LINK_TEXT = "partial link text" # NAME = "name" # TAG_NAME = "tag name" # CLASS_NAME = "class name" # CSS_SELECTOR = "css selector" ele.click() driver.back() # 查找多个元素的方法 eles = driver.find_elements_by_class_name("Feed") print(eles) print(len(eles)) time.sleep(5) eles = driver.find_elements(By.CLASS_NAME, 'Feed') # XPATH = "xpath" # LINK_TEXT = "link text" # PARTIAL_LINK_TEXT = "partial link text" # NAME = "name" # TAG_NAME = "tag name" # CLASS_NAME = "class name" # CSS_SELECTOR = "css selector" print(eles) print(len(eles)) driver.quit()
以上就是定位元素的一些方法。说明下xpath是比较好用的方式,之后可以多多练习使用xpath进行定位元素。
前面所介绍的几种定位方法相对来说比较简单,我们理想状态下在一个页面当中每一个元素都会有一个唯一 id 和 name 属性值,我们通过它的属性值来找到他们,但在实际的项目中并非想象的这般美好。有时候一个元素并没有 id 或 name 属性,或者会有多个元素的
id 和 name 属性值是一样的,又或者每一次刷新页面,id 的值都会随机变化。那么在这种情况下我们如何来定位元素呢?
下面一篇介绍 xpath 与 CSS 定位相比上面介绍的方式来说比较难理解,但他们的灵活的定位能力远比上面的几种方式要强大得多。
那么下面宏哥接下来就分享一下xpath的相关知识。
好了,今天python+ selenium-驱动浏览器和元素定位大法就分享到这里。