Selenium是一套Web网站的程序自动化操作解决方案。
selenium 自动化流程如下:
自动化程序调用Selenium 客户端库函数(比如点击按钮元素)
客户端库会发送Selenium 命令 给浏览器的驱动程序
浏览器驱动程序接收到命令后 ,驱动浏览器去执行命令
浏览器执行命令
浏览器驱动程序获取命令执行的结果,返回给我们自动化程序
自动化程序对返回结果进行处理
id是元素的编号, 是用来在html中标记该元素的,根据规范, 如果元素有id属性 ,这个id 必须是当前html中唯一的。
自动化在浏览器中 访问股票搜索网站,并且在输入框中搜索 通讯
from selenium import webdriver
from selenium.webdriver.common.by import By
# 创建 WebDriver 对象
wd = webdriver.Chrome()
# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.byhy.net/_files/stock1.html')
# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element(By.ID, 'kw')
# 输入字符串到 这个 输入框里
element.send_keys('通讯\n')
这段代码是发起一个请求,通过浏览器驱动转发给浏览器,告诉它需要选择一个id为 kw 的元素。浏览器找到id为kw的元素后,将结果通过浏览器驱动返回给自动化程序,所以 find_element 方法会返回一个 WebElement 类型的对象。
元素也有类型, class 属性就用来标志着元素类型
所有的植物元素都有个class属性 值为 plant。所有的动物元素都有个class属性 值为 animal。
如果我们要选择 所有的动物, 就像下面可以这样写
wd.find_elements(By.CLASS_NAME, 'animal')
注意element后面多了个s
find_elements 返回的是找到的符合条件的 所有 元素 (这里有3个元素), 放在一个 列表 中返回。而如果我们使用 wd.find_element (注意少了一个s) 方法, 就只会返回 第一个 元素。
通过 WebElement 对象的 text属性可以获取该元素在网页中的文本内容。
元素也可以有 多个class类型 ,多个class类型的值之间用 空格 隔开,比如chinese和student:
张三
我们要用代码选择这个元素,可以指定任意一个class 属性值,都可以选择到这个元素,如下
element = wd.find_elements(By.CLASS_NAME,'chinese')
或者
element = wd.find_elements(By.CLASS_NAME,'student')
不能写成(By.CLASS_NAME,'chinese student')
我们可以通过指定 参数为 By.TAG_NAME ,选择所有的tag名为 div的元素
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Chrome()
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')
# 根据 tag name 选择元素,返回的是 一个列表
# 里面 都是 tag 名为 div 的元素对应的 WebElement对象
elements = wd.find_elements(By.TAG_NAME, 'div')
# 取出列表中的每个 WebElement对象,打印出其text属性的值
# text属性就是该 WebElement对象对应的元素在网页中的文本内容
for element in elements:
print(element.text)
WebElement对象 也可以调用 find_elements, find_element 之类的方法
WebDriver 对象 选择元素的范围是 整个 web页面, 而
WebElement 对象 选择元素的范围是 该元素的内部。
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Chrome()
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')
element = wd.find_element(By.ID,'container')
# 限制 选择元素的范围是 id 为 container 元素的内部。
spans = element.find_elements(By.TAG_NAME, 'span')
for span in spans:
print(span.text)
我们点击搜索后网页服务器需要处理才能把结果返回给浏览器,需要一定时间,所以我们需要在点击搜索后将代码睡眠一定时间sleep()
Selenium提供了一个合理的解决方案,是这样的:
当发现元素没有找到的时候, 并不立即返回 找不到元素的错误。而是周期性(每隔半秒钟)重新寻找该元素,直到该元素找到,或者超出指定最大等待时长,这时才 抛出异常。Selenium 的 Webdriver 对象 有个方法叫 implicitly_wait ,可以称之为 隐式等待 ,或者 全局等待 。该方法接受一个参数, 用来指定 最大等待时长。
from selenium import webdriver
from selenium.webdriver.common.by import By
wd = webdriver.Chrome()
wd.implicitly_wait(10)
wd.get('https://www.byhy.net/_files/stock1.html')
element = wd.find_element(By.ID, 'kw')
element.send_keys('通讯\n')
# 返回页面 ID为1 的元素
element = wd.find_element(By.ID,'1')
print(element.text)