安装
selenium直接使用pip安装即可,之后还需要安装浏览器的驱动,比如火狐的geckodriver。
对于Windows,只需要下载对应的EXE文件后,把它放在Python安装目录的scripts目录中即可。其实浏览器驱动可以放在任意的位置,只需在创建webdriver对象是执行驱动的路径即可。
对于Linux,下载driver的zip包,解压后放入/usr/bin目录即可。
API介绍
API | 说明 |
---|---|
selenium.common.exceptions |
异常类的包 |
selenium.webdriver |
所有驱动浏览器相关的API都在这个包里 |
selenium.webdriver.__init__.py |
导入webdriver类和options类,并取别名 |
selenium.webdriver.chrome.webdriver.py |
里面就一个WebDriver类 |
selenium.webdriver.chrome.options |
里面就一个Options类 |
selenium.webdriver.remote.webdriver.py |
仅有一个WebDriver类,是其他webdriver的父类 |
selenium.webdriver.remote.webelement.py |
仅有一个WebElement类,表示webdriver找到的元素 |
selenium.webdriver.firefox.webelement.py |
火狐有自己的webelement类 |
selenium.webdriver.common.by.py |
只有一个By类,用来指定查找元素时用的方式 |
selenium.webdriver.common.keys.py |
只有一个Keys类,定义了一些按键,比如ctrl、shift |
selenium.webdriver.common.action_chains |
只有一个ActionChains类,可以构建该类的对象,完成组合键操作 |
selenium.webdriver.support.wait.py |
只有一个WebDriverWait类,显示等待相关 |
selenium.webdriver.support.expected_conditions |
这个模块里每一个类都代表了一种条件,显示等待相关 |
浏览器控制
from selenium import webdriver
try:
# 等效于:
# browser=webdriver.chrome.webdriver.WebDriver()
browser=webdriver.Chrome()
browser.get("https://cn.bing.com")
finally:
browser.close()
browser对象有如下成员
- back()/forward():后退/前进
- close():关闭当前窗口
- quit():关闭所有窗口
- get():再当前窗口加载新页面
- save_screenshot(filename):保存当前页面截图,png格式
- get_screenshot_as_file(filename):同上
- maximize_window()/minimize_window():最大化最小化窗口
-
execute_script(*args)/execute_async_script(*args)
:执行JS脚本 - current_window_handle:当前窗口的句柄,是一个字符串
- window_handles:所有窗口的句柄
切换标签页
使用快捷键或是JS代码可以打开新的标签
ActionChains这种方法常常会有问题,不推荐使用。比如我遇到过能用ctrl+a全选,但是不能使用ctrl+t打开新标签。
试了一下发现凡是浏览器窗口相关的快捷键都不能用,比如ctrl+f、ctrl+n、ctrl+j,但是页面相关的可以用,比如ctrl+enter(在新标签中打开链接)
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
browser=webdriver.Chrome()
browser.get('http://localhost:8888')
pydoc_handle=browser.current_window_handle
# 按下 ctrl t 打开新标签,不推荐使用
# ActionChains(browser).key_down(Keys.CONTROL).send_keys("t").key_up(Keys.CONTROL).perform()
browser.execute_script('window.open()')
# 这个句柄是一个id,没规律,只能每次打开新标签都遍历一下,找到新标签的句柄
for i in browser.window_handles:
if i != pydoc_handle:
browser.switch_to.window(i)
chrome启动参数
比如下面的chrome headless,常用的还有 --start-maximized 最大化
新版selenium不再支持phantomJS,建议使用chrome headless。
正常安装selenium和chromedriver,使用时加上参数即可。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(chrome_options=chrome_options)
元素定位
webdriver和webelement对象可以使用如下方法查找子元素。如果找到的元素有多个,则只取第一个元素。
- find_element_by_id
- find_element_by_name:根据html元素的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
-
find_element(By.ID, id)
:需要指定查找的方式,比如根据id来查找
将上面的find_element_*
改为find_elements_*
即可查找多个元素,找到后会存入一个list中返回。
元素交互
webelement的一下方法:
- click()
- clear()
- send_keys(*args)
- get_attribute(name)
webelement.text有遇到无法取得文本节点的情况,不知道为什么。改用webelement.get_attribute('innerText')就可以了。
隐式等待元素加载
driver.implicitly_wait(time_out_sec)
作用于整个driver,每次find element时,如果element没有被找到,就会等待,超出最长等待时间后还没找到,依旧会去执行下一步。
如果在timeout之内找到element,那就执行下一步,不会继续等待了。
显式等待元素加载
和隐式等待效果一样,区别是它只等待指定的某一个element;如果超时了还找不到,抛出异常
隐式等待和显式等待可以一起使用,等待时间取两者的最大值
# 官方例子,等待某一个元素消失
# 30:最长等待时间,second
# 1:等待期间每隔1秒去检查等待条件是否达成,默认是0.5秒
# (ElementNotVisibleException,):可迭代对象,检查等待条件是否达成时,忽略部分异常,默认忽略NoSuchElementException
WebDriverWait(driver, 30, 1, (ElementNotVisibleException,)).\
until_not(lambda x: x.find_element_by_id("someId").is_displayed())
# untile_not:接受一个callable作为参数,直到callable返回False,或者超时,才会去执行后面的代码
# 返回False指的是返回False这个bool值,而不是仅仅是表示【假】的这种值
# 这个callable接受一个参数,而且传入的应该就是driver
# -----------
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
locator = (By.LINK_TEXT, 'CSDN')
WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
# presence_of_element_located,当元素存在时,条件成立
网友评论