Selenium是一个用于Web应用程序测试的工具,Selenium测试直接运行在浏览器中,就像真正的用户操作一样。支持的浏览器包括IE(7,8,9,10,11),Mozilla Chrome,Safari,Google Chrome,Opea等。最初是为网站自动化测试而开发的,就像玩游戏用的按键精灵,可以按指定的命令自动操作。
Selenium可以根据的指令让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生等。
如图所示,通过Python来控制Selenium,然后让Selenium控制浏览器,操控浏览器,这样就实现了使用Python间接操控的浏览器。
这里选择的是电脑自带的Microsoft Edge,打开设置—关于Microsoft Edge。查看Edge的版本115.0.1901.203。
输入驱动器下载网址:Microsoft Edge WebDriver - Microsoft Edge Developer
根据自身浏览器版本下载对应的驱动器。
打开文件,把驱动器拖拽到PycharmProject文件夹中即可使用(这里拖拽到Python文件目录下也是可以的)
from selenium import webdriver
driver = webdriver.Edge()
driver.get('https://www.baidu.com/') # 打开百度首页
driver.quit() # 退出浏览器
通过selenium的基本使用可以简单定位元素和获取对应的数据,以下是定位元素的方法:
find_element(By.ID, 'id属性值') # (根据id属性值获取元素)
find_element(By.NAME, 'name属性值') # (根据标签的name属性) find_element(By.CLASS_NAME, '类属性值') #(根据类名获取元素) find_element(By.LINK_TEXT, '标签文本') #(根据标签的文本获取元素,精确定位) find_element(By.PARTIAL_LINK_TEXT, '标签文本') #(根据标签包含的文本获取元素,模糊定位)
find_element(By.TAG_NAME, '标签名') #(根据标签名获取元素)
find_element(By.XPATH, 'xpath语法') #(根据xpath获取元素) find_element(By.CSS_SELECTOR, 'css语法') # (根据css选择器获取元素)
find_element只会查找页面中符合条件的第一个节点,并返回。如果想获取多个元素可以在element后面加s,这样返回的是列表。
id定位就是通过元素的id属性来定位元素,在html中元素的id是唯一的。
html规定name属性来指定元素名称,name的属性值在当前文档中可以不是唯一的,name定位就是根据name属性来定位,如果存在多个相同属性,那么默认定位到的是第一个。
html规定class来指定元素的类名,class定位就是根据class属性来定位。在html中元素的class不是唯一的,是可以重复的。如果存在多个相同属性,那么默认定位到的是第一个。
通过超链接的文本定位元素。link_text定位的是超链接的全部文本内容,所以匹配条件为绝对匹配(精确匹配)。
partial_link_text为link_text的补充,partial_link_text定位的是超链接的局部文本内容,所以匹配条件为部分匹配就满足条件,只截取一部分字符串,进行模糊匹配。
html通过tag来定义一类功能,比如html是网页的根标签,head是头部标签,title是网页自身的标题标签,body是主体标签。由于一个tag用来定义一类功能,一个网页往往有很多同类tag,所以很难通过tag去区分不同的元素。
XPath,全称 XML Path Language,即 XML 路径语言,它是一门在XML文档中查找信息的语言。XPath 最初设计是用来搜寻XML文档的,但是它同样适用于 HTML 文档的搜索。XPath 的选择功能十分强大,它提供了非常简洁明了的路径选择表达式。
绝对路径定位存在很大的问题就是如果页面元素改变,Xpath会随着页面的布局的改变而改变,不利于维护。性能差,因为使用这种方式进行定位,Webdriver会将整个页面的所有元素进行扫描来找到我们所需的元素,所以当脚本中大量使用XPath方式定位,会大大降低脚本的执行速度。
关于XPATH的具体用法。
CSS Selector语法选择元素原理为通过css样式进行选择。CSS配合HTML来工作,它实现的原理是匹配对象的原理,而XPATH是配合XML工作,它实现的原理是遍历的原理,在两者设计上,CSS性能更为优秀。
关于CSS_SELECTOR的具体用法。
当我们通过selenium实例化一个浏览器对象时,可以针对此对象进行操作,常见的操作有:
函数 | 用法 |
driver.get('url') | 根据url地址访问站点 |
driver.page_source | 查看页面渲染之后的html数据 |
driver.get_cookies() | 查看页面请求后生成的cookies,可以用此方法拿到加密的cookies |
driver.current_url | 查看当前页面的url |
driver.maximize_window() | 最大化浏览器 |
driver.minimize_window() | 最小化浏览器 |
driver.close() | 关闭当前页面,注意不是关闭整个浏览器 |
driver.quit() | 关闭浏览器 |
driver.back() | 回退到上一级页面 |
driver.forward() | 前进到下一级页面 |
switch_to() | 切换窗口以及嵌套网页 |
click() | 执行点击操作 |
text | 获取元素包含的文本内容 |
get_attribute('属性名') | 获取元素的属性值 |
send_keys('context') | 键入文本 |
clear() | 清空输入框 |
关于close()和quit()的区别:
当使用close方法的时候,关闭当前窗口,如果它是当前打开的最后一个窗口,则退出浏览器,但是通过查看任务管理器发现,EdgeDriver进程仍存在内存中。如果使用quit方法,整个浏览器都直接关闭,EdgeDriver进程也会被结束。
嵌套页面就是在一个HTML页面中嵌套了子页面。嵌套页面的表现形式以及在HTML源代码表现形式如下图:
在我们使用selenium操作此类网页时一定要注意操作的页面是不是在嵌套页面,使用selenium获取嵌套页面的数据,首先我们要进入到嵌套页面里面,不然是获取不到数据的。进入嵌套页面可以使用实例化浏览器对象的switch_to.frame()方法。
如下代码的操作是向信息搜索中键入“统计年鉴2022”并点击高级搜索。
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
driver = webdriver.Edge()
driver.get('http://tjj.shanxi.gov.cn/tjsj/tjnj/')
driver.implicitly_wait(10)
driver.maximize_window()
driver.switch_to.frame(driver.find_element(By.XPATH, '//*[@id="rightFrame"]'))
driver.find_element(By.XPATH,'//*[@id="j_search"]').send_keys('统计年鉴2022')
driver.find_element(By.XPATH,'//*[@id="search_button"]').click()
time.sleep(5)
driver.quit()
点击某个按钮后,页面是在一个新的浏览器中出现。例如运行3.1的代码后,此时的浏览器停留在了名为“山西省统计局”的页面上,但是selenium的driver还停留在旧页面上,导致无法操作。需要使用selenium的窗口切换功能,将driver切换到新页面之后再进行操作。
driver.switch_to.window(driver,window_handles[-1]) #切换到最新窗口
里面的参数如果为0就是浏览器的第一个窗口,参数为1就是第二个,依此类推......
在使用selenium操作网页时,有的网页需要滚动鼠标滚轮下拉 页面,才会给我们加载页面的下部分数据。JavaScript 可以直接在浏览器中运行,那么这样的操作可以让selenium执行 JavaScript代码来完成。
js="var q=document.documentElement.scrollTop=750"
driver.execute_script(js)
js = "window.scrollTo(0, document.body.scrollHeight)"
driver.execute_script(js)
js = "window.scrollTo(0, 0)"
driver.execute_script(js)
有些时候,需要在页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,可以通过导入 ActionChains 类来做到。
click() | 单击指定的元素 |
click_and_hold() | 按住元素上的鼠标左键,并保持 |
context_click() | 对元素执行上下文单击 |
double_click() | 双击一个元素 |