Selenium + WebDriver 实现控制浏览器
2018-04-12 本文已影响0人
Manchangdx
首先,安装浏览器和驱动,参见 Ubuntu 安装 Chrome 浏览器和 chromedriver
1、在 ipython 中引入 webdriver :
In [1]: from selenium import webdriver
In [2]: driver = webdriver.Chrome() # 这就开始了,用驱动控制浏览器的打开
...: driver.get('https://www.baidu.com') # 打开百度搜索的页面
...:
2、查看一些信息:
In [3]: driver.title # 标题,就是浏览器标签上的内容
Out[3]: '百度一下,你就知道'
In [4]: driver.page_source[:55] # HTML 源代码,忒长,截取一部分查看一下
Out[4]: '<!DOCTYPE html><!--STATUS OK--><html xmlns="http://www.'
In [5]: driver.current_url # 查看当前页面的地址
Out[5]: 'https://www.baidu.com/'
3、定位元素之术:
# ---------- id 定位 ----------
# 定位 id 属性值为 'kw' 的元素,也就是搜索框
# 因为 id 属性值为 'kw' 的元素在这个页面的源码中只有一个,所以可以这样写
In [6]: driver.find_element_by_id('kw')
Out[6]: <selenium.webdriver.remote.webelement.WebElement (session="ec..."
# ---------- name 定位 ----------
# 定位 name 属性值为 'wd' 的元素,亦可定位搜索框
In [7]: driver.find_element_by_name('wd')
Out[7]: <selenium.webdriver.remote.webelement.WebElement (session="ec..."
# 定位搜索框,并把 'NBA' 写入搜索框
# 如果此时搜索框为空,那么写入后自动回车;否则只写入,不搜索(待考证)
In [8]: driver.find_element_by_id('kw').send_keys('NBA')
# ----------- class 定位 ----------
# 定位 class 属性值为 's_ipt' 的元素,即搜索框
In [9]: driver.find_element_by_class_name('s_ipt').send_keys('NBA')
# 写入要搜索的内容到搜索框后,如果未自动搜索
# 可以执行此命令定位 id 值为 'su' 的元素,也就是 “百度一下” 那个提交按钮
# click 就是点击
In [12]: driver.find_element_by_id('su').click()
# 定位搜索框并清空之
In [13]: driver.find_element_by_id('kw').clear()
4、控制页面前进和后退:
In [14]: driver.forward() # 前进
In [15]: driver.back() # 后退
In [16]: driver.refresh() # 刷新
5、根据元素的 text 值定位元素:
# 根据上面的命令已经控制浏览器使用百度搜索了 NBA 这个关键字,搜索结果如上图所示
# 现在我们要点击第一条搜索结果,即 ”NBA常规赛_腾讯体育“
# 首先引入这个工具
In [36]: from selenium.webdriver.common.by import By
# 然后定位这个 text ,执行 click 即可
In [37]: driver.find_element(By.LINK_TEXT, 'NBA常规赛_腾讯体育').click()
# ---------- link 定位 ----------
# 或者使用 link 定位 text 值为 'NBA常规赛_腾讯体育' 的链接
In [38]: driver.find_element_by_link_text('NBA常规赛_腾讯体育').click()
6、试一下 Google 搜索:
In [46]: driver.get('https://www.google.com.hk/')
# 向输入框写入 ”实验楼“ 三个字
# 它这个并未顺便执行搜索,跟百度不大一样
In [47]: driver.find_element_by_id('lst-ib').send_keys('实验楼')
# ---------- CSS 定位 ----------
# 通过某个属性的值来定位
# 点 ”Google 搜索“ 那个按钮
In [54]: driver.find_element_by_css_selector(
...: '[value="Google 搜索"]').submit()
...:
# 另一种写法
In [55]: driver.find_element_by_css_selector(
...: 'input[name="btnK"]').click()
...:
# ---------- xpath 定位 ----------
# 用 xpath 定位到想要的 input 标签
In [56]: driver.find_element_by_xpath(
...: '//input[@name="btnK"]').click()
...:
7、等待页面加载完成
现在大多数 Web 应用程序都使用 Ajax 技术
当一个页面被加载到浏览器时,该页面内的元素可以在不同的时间点被加载
这使得定位元素变得困难
如果元素不在页面之中,定位此元素会抛出 ElementNotVisibleException 异常
因为代码运行速度太快,而浏览器渲染页面很慢
所以为了避免报错,只能让代码运行等待浏览器渲染
Selenium 提供两种等待方式:显式和隐式
先说显式等待:
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
对上面的 4 行代码解释一下
第 1 行不说了
第 2 行 WebDriverWait 就是显式等待类,用法及参数:
WebDriverWait(driver, 超时时长, 调用频率).until(可执行方法, 超时时返回的信息)
第 3 行 EC 简单说就是用来作判断的,后面会举例
第 4 行 By 上面有例子,是一种特殊的查找元素的方法
WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element(
(By.XPATH, '//ul[@class="pgntion"]/li[@class="active"]'), # 代码块
str(page) # 字段
)
)
上面代码是个例子
第 2 行 text_to_be_present_in_element 是一个判断方法,判断某代码块中是否存在某字段
下面说一下隐式等待:
driver.implicitly_wait(30)
就上面这一行~
这个方法介绍网上介绍得七七八八,有时间看一下源码再补充
还有一种 python 方法,强制等待:
from time import sleep
sleep(10) # 强制等待 10 秒