1. 准备工作
install selenium
首先安装 selenium 库:
pip install selenium
安装完成后可以参考 selenium 文档 初步了解 selenium
install chromedriver
接着安装 chromedriver,因为我们需要通过 python 控制 Chrome 浏览器,因此需要安装它。根据 Chrome 的版本下载对应的 chromedriver。下载后将 chromedriver 放入 Python 和 Chrome 的安装目录下并添加环境变量。
测试一下
import time
from selenium import webdriver
# 打开 Chrome
driver = webdriver.Chrome()
#打开网址
url = 'https://www.baidu.com'
driver.get(url)
# 搜索 HNU
driver.find_element_by_id("kw").click()
driver.find_element_by_id("kw").send_keys("HNU")
driver.find_element_by_id("su").click()
# close window
time.sleep(5)
driver.close()
此时能够打开 Chrome 并搜索 HNU ~
若失败,可以根据报错信息看看添加环境遍历是否成功、chromedriver 的版本是否与 Chrome 匹配!
2. 打开页面
打开页面只需要通过 webdriver
的 get
函数:
from selenium inport wedriver
driver = webdriver.Chrome()
url = "https://www.baidu.com"
driver.get(url)
2.1 页面交互
定位元素
webdriver 提供了大量查找元素的方式,通过定位元素我们可以模拟各种操作:
<input type="text" name="passwd" id="passwd-id">
此时可以通过以下方式查找它:
element = driver.find_element_by_id("passwd-id")
element = driver.find_element_by_name("passwd-id")
element = driver.find_element_by_id("passwd-id")
若查找失败,返回 NoSuchElementException
异常
模拟输入
通过 send_keys()
函数输入内容:
element.send_keys("HNU")
也可以模拟按键输入:
from selenium.webdriver.common.keys import Keys
element.send_keys("HNU", Keys.ENTER) # 输入 HNU 后回车
除了这些外,selenium 也可以模拟拖放、表单填写、窗口切换、处理弹窗、访问历史记录等功能。
3. 查找元素
Selenium 提供了下列查找的方法:
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
除了通过 ID 查找的方式外,其他方式可以通过加S选择多个元素,如:
find_elements_by_class_name() # find all
find_elements_by_css_selector() # find all
3.1 ID & Name
<input type="text" name="username" id="username">
选择该标签:
element = driver.find_element_by_id('username')
element = driver.find_element_by_name('username')
3.2 CSS selector
当你向通过 CSS 选择器查找元素时,页面中第一个匹配该 CSS 选择器的元素 会被匹配并返回。
如选择下面的 p 标签:
<html>
<body>
<p class="content">Site content goes here.</p>
</body>
<html>
python 代码如下:
content = driver.find_element_by_css_selector('p.content')
3.3 link text
可以通过链接文本获取超链接,如:
<html>
<body>
<p>Are you sure you want to do this?</p>
<a href="continue.html">Continue</a>
<a href="cancel.html">Cancel</a>
</body>
<html>
以下两种方式都可以选择超链接:
link1 = driver.find_element_by_link_text('Continue')
links = driver.find_elements_by_partial_link_text('tinue')
4. 等待页面加载完成
当一个页面被加载到浏览器时, 该页面内的元素可以在不同的时间点被加载。这使得定位元素变得困难,如果元素不再页面之中,会抛出 ElementNotVisibleException
异常。
4.1 强制等待
定义:设置固定休眠时间,单位为秒。通过 time.sleep()
实现,但使用起来不方便!
driver.get(url)
time.sleep(3)
4.2 隐式等待
当使用了隐式等待执行测试的时候,如果 WebDriver 没有在 DOM 中找到元素,将继续等待,超出设定时间后则抛出找不到元素的异常
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.implicitly_wait(10)
driver.find_element_by_id("kw").send_keys("HNU")
driver.find_element_by_id("su").click()
隐性等待对 整个 driver 的周期都起作用,所以只要设置一次即可,同时隐式等待会让测试速度变慢!
4.3 显式等待
定义:等待某个条件成立时继续执行,否则在达到最大时长时抛出异常
WebDriverWait
类是由 webdriver 提供的等待方法,配合该类提供的 until()
和 until_not()
方法一起使用,就可以根据判断条件灵活的进行等待。
调用方法:
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None).until()
参数如下:
parameters | description |
---|---|
driver | 传入WebDriver实例,浏览器驱动 |
timeout | 超时时间,最大等待时间 |
poll_frequency | 调用until或until_not中的方法间隔时间,默认是0.5秒 |
ignored_exceptions | 忽略的异常,默认包含 NoSuchElementException |
until
为当某元素出现或满足条件时继续执行,包含两个参数:
method
—— 等待期间每隔一段时间传入的方法,知道返回值为true
message
—— 超时将 message 传入异常
举个例子:
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, 'logo')))
其中 ES
为 selenium 提供的一个模块,presence_of_element_located
意思为元素被加载到了 DOM 树中。
5. WebDriver API
当需要使用特定 API 时,可以查阅 WebDriver API
控制浏览器常用方法:
- set_window_size() 设置浏览器的大小
- back() 控制浏览器后退
- forward() 控制浏览器前进
- refresh() 刷新当前页面
- clear() 清除文本
- send_keys (value) 模拟按键输入
- click() 单击元素
- submit() 用于提交表单
- get_attribute(name) 获取元素属性值
- size 返回元素的尺寸
- text 获取元素的文本
# 页面刷新
driver.refresh()
# 返回到上一页
driver.back()
# 前进到下一页
driver.forward()
# 窗口最大化
driver.maximize_window()
# close
driver.close()
# screenshot
driver.save_screenshot('screenshot.png')
6. 实例
将 bilibili 的所有分类打印出来:
import time
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome()
driver.implicitly_wait(8)
driver.get('https://www.bilibili.com/')
categories = driver.find_elements_by_xpath('//div[@id="primaryChannelMenu"]/span/div/a/span')
for category in categories:
print(category.text)
time.sleep(1)
REFERENCE: