selenium.webdriver提供了所有WebDriver的实现,目前支持FireFox、phantomjs、Chrome、Ie和Remote
安装seleniun
pip install selenium
新建实例driver = webdriver.Chrome()
方法:find_element_by_id(element_id)
实例:driver.find_element_by_id(“iptUsername”)
element = driver.find_element_by_id("coolestWidgetEvah")
# 或者
from selenium.webdriver.common.by import By
element = driver.find_element(by=By.ID, value="coolestWidgetEvah")
方法:find_element_by_name(element_name)
实例:driver.find_element_by_name(“inputPwname”)
cheese = driver.find_element_by_name("cheese")
# 或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.NAME, "cheese")
方法:find_element_by_xpath(xpath)
实例:driver.find_element_by_xpath("//div[@id='menuContainer']/div/div/ul/li[4]/a")
inputs = driver.find_elements_by_xpath("//input")
# 或者
from selenium.webdriver.common.by import By
inputs = driver.find_elements(By.XPATH, "//input")
方法:find_element_by_tag_name(tag_name)
实例:driver.find_element_by_tag_name(“input”)
注意:通过tag_name查找时使用find_element_by_tag_name查找到的是第一个标签的tag_name
frame = driver.find_element_by_tag_name("iframe")
# 或者
from selenium.webdriver.common.by import By
frame = driver.find_element(By.TAG_NAME, "iframe")
方法:tag_name
实例:driver.find_element_by_id(“iptUsername”).tag_name
方法:find_element_by_link_text(link_text)
实例:driver.find_element_by_link_text(‘登 录’)
cheese = driver.find_element_by_link_text("cheese")
# 或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.LINK_TEXT, "cheese")
search for cheese>
实现
cheese = driver.find_element_by_partial_link_text("cheese")
# 或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.PARTIAL_LINK_TEXT, "cheese")
方法:find_elements_by_class_name(class_name)
实例:driver.find_elements_by_class_name(“x-panel-body”)
cheeses = driver.find_elements_by_class_name("cheese")
# 或者
from selenium.webdriver.common.by import By
cheeses = driver.find_elements(By.CLASS_NAME, "cheese")
方法:find_element_by_css_selector()
实例:driver.find_element_by_css_selector(“input.btn”)
温馨提示:find_elements_by_css_selector()查询到的是一个集合,如果id名字重复的时候可以采取find_elements_by_id(),其他的查询方式同理;
通过CSS的定位策略。默认情况下本机浏览器支持CSS定位,所以,请参考W3C CSS选择器http://www.w3.org/TR/CSS/#selectors显示一般可用的CSS选择器的列表。如果浏览器没有原生支持CSS查询,可以使用Sizzle(Sizzle是一个纯javascript CSS选择器引擎)。目前,IE 6,7和FF3.0使用Sizzle的CSS查询引擎。
注意:不是所有浏览器对CSS的支持都是一样的,可能在一个浏览器中运行良好,切换到另一个浏览器则不然。
cheese = driver.find_element_by_css_selector("#food span.dairy.aged")
# 或者
from selenium.webdriver.common.by import By
cheese = driver.find_element(By.CSS_SELECTOR, "#food span.dairy.aged")
在高的级别上,尽可能的使用一个浏览器原生的webdriver XPath 的功能。在一些没有本地的XPath支持的浏览器,我们已经提供了我们自己的实现。这可能会导致一些意想不到的行为,除非你知道各种XPath引擎的差异。
驱动 | 标签和属性名称 | 属性值 | 本地的XPath支持 |
---|---|---|---|
HtmlUnit Driver | 小写 | 当他们出现在HTML | 是 |
Internet Explorer Driver | 小写 | 当他们出现在HTML | 没有 |
Firefox Driver | 不区分大小写 | 当他们出现在HTML | 是 |
这点抽象,对于下面这段HTML 代码来说:
inputs = driver.find_elements_by_xpath("//input")
or
from selenium.webdriver.common.by import By
inputs = driver.find_elements(By.XPATH, "//input")
不同驱动对大小写的支持:
XPath expression | HtmlUnit Driver | Firefox Driver | Internet Explorer Driver |
---|---|---|---|
//input | 1 (“example”) | 2 | 2 |
//INPUT | 0 | 2 | 0 |
HTML元素有时并不需要显式地声明,因为他们默认为已知值的属性。例如,“input”的标签并不需要的“type”属性,因为它默认为“text”。webdriver使用XPath时,你不应该期望能够对这些隐含的属性相匹配。
方法:get_cookies()
实例:driver.get_cookies()
方法:driver.get_cookie(cookie_name)
实例:driver.get_cookie(“NET_SessionId”)
方法:delete_all_cookies()
实例:driver.delete_all_cookies()
方法:delete_cookie(name)
实例:deriver.delete_cookie(“my_cookie_name”)
例子:
#转到正确的域
driver.get("http://www.example.com")
#现在在这里的整个域设置的cookie,
#这里的cookie的名称是'key',它的值是'value'的
driver.add_cookie({'name':'key', 'value':'value', 'path':'/'})
# additional keys that can be passed in are:
# 'domain' -> String,
# 'secure' -> Boolean,
# 'expiry' -> Milliseconds since the Epoch it should expire.
# 现在的输出当前URL的所有可用的cookies
for cookie in driver.get_cookies():
print "%s -> %s" % (cookie['name'], cookie['value'])
driver.delete_cookie("CookieName")
driver.delete_all_cookies()
口的坐标**
方法:get_window_position()
实例:driver.get_window_position()
方法:get_window_size()
实例:driver.get_window_size()
方法:location
解释:首先查找到你要获取元素的,然后调用location方法
实例:driver.find_element_by_xpath("//*[@id='tablechart']/tbody/tr[14]/td[9]").location
方法:size
实例:driver.find_element_by_id(“iptPassword”).size
返回值:{‘width’: 250, ‘height’: 30}
方法:value_of_css_property(css_name)
实例:driver.find_element_by_css_selector("input.btn").value_of_css_property("input.btn")
driver.find_element_by_id("sellaiyuan").get_attribute("@href")
driver.find_element_by_id("sellaiyuan").get_attribute("textContent")
方法:text
实例:driver.find_element_by_id(“iptUsername”).text
有些时候,我们需要再页面上模拟一些鼠标操作,比如双击、右击、拖拽甚至按住不动等,我们可以通过导入 ActionChains 类来做到:
#导入 ActionChains 类,ActionChains鼠标操作类
from selenium.webdriver import ActionChains
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys #引入keys类操作
# 鼠标移动到 ac 位置
ac = driver.find_element_by_xpath('element')
ActionChains(driver).move_to_element(ac).perform()
move_to_element(ac):移动鼠标到一个元素中,ac上面已经定义了他所指向的哪一个元素
to_element:元件移动到
perform():执行所有存储的行为
# 移动操作
article = driver.find_element_by_link_text(u'周碧华:社科院出现内鬼意味着什么?')
ActionChains(driver).move_to_element(article).perform()#将鼠标移动到这里,但是这里不好用
ActionChains(driver).context_click(article).perform()
# 在 ac 位置单击
ac = driver.find_element_by_xpath("elementA")
ActionChains(driver).move_to_element(ac).click(ac).perform()
# 在 ac 位置双击
ac = driver.find_element_by_xpath("elementB")
ActionChains(driver).move_to_element(ac).double_click(ac).perform()
# 在 ac 位置右击
ac = driver.find_element_by_xpath("elementC")
ActionChains(driver).move_to_element(ac).context_click(ac).perform()
# 在 ac 位置左键单击hold住
ac = driver.find_element_by_xpath('elementF')
ActionChains(driver).move_to_element(ac).click_and_hold(ac).perform()
# 将 ac1 拖拽到 ac2 位置
ac1 = driver.find_element_by_xpath('elementD')
ac2 = driver.find_element_by_xpath('elementE')
ActionChains(driver).drag_and_drop(ac1, ac2).perform()
方法:submit
解释:查找到表单(from)直接调用submit即可
实例:driver.find_element_by_id(“form1”).submit()
我们已经知道了怎样向文本框中输入文字,但是有时候我们会碰到标签的下拉框。直接点击下拉框中的选项不一定可行。
Selenium 专门提供了 Select 类来处理下拉框。
其实 WebDriver 中提供了一个叫 Select 的方法,可以帮助我们完成这些事情:
# 导入 Select 类
from selenium.webdriver.support.ui import Select
# 找到 name 的选项卡
select = Select(driver.find_element_by_name('status'))
#
select.select_by_index(1)
select.select_by_value("0")
select.select_by_visible_text(u"未审核")
以上是三种选择下拉框的方式,它可以根据索引来选择,可以根据值来选择,可以根据文字来选择。注意:
"""
index 索引从 0 开始
value是option标签的一个属性值,并不是显示在下拉框中的值
visible_text是在option标签文本的值,是显示在下拉框的值
全部取消选择怎么办呢?很简单:
select.deselect_all()
"""
用户输入-填写表单
我们已经看到了如何将文字输入到一个文本或文本字段,但其他元素?您可以“切换”复选框的状态,你可以使用“点击”设置类似选择的选项标记。处理SELECT标签是不是太糟糕:
select = driver.find_element_by_tag_name("select")
allOptions = select.find_elements_by_tag_name("option")
for option in allOptions:
print "Value is: " + option.get_attribute("value")
option.click()
找到页面上第一个“select”的元素,并通过每个选项依次循环,打印出它们的值。你会发现,这不是最有效处理SELECT元素的方式。在webdriver的支持类中,有一个名为“select”,它提供了一些有用的方法,来处理这些交互。
# available since 2.12
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_tag_name("select"))
select.deselect_all()
select.select_by_visible_text("Edam")
从页面上第一个选择开始取消所有选项,从第一个选择页面上的所有选项,然后选择显示的文本与“Edam” 的选项。
当你完成填写表格,你可能要提交。我们需要找到“提交”按钮,然后单击它:
driver.find_element_by_id("submit").click()
另外,有方便的方法可以在webdriver的每个元素上的“提交”。如果调用此表单内的元素,webdriver通过的DOM按顺序找到封闭的形式,然后调用该提交。如果该元素不是一种形式,那么会抛出NoSuchElementException异常:
element.submit()
如今大多数Web应用程序使用ajax技术,当浏览器在加载页面时,页面上的元素可能并不是同时被加载完成,这给定位元素的定位增加了困难,
如果因为在加载某个元素时延迟而造成ElementNotVisibleException(不可见元素异常)的情况出现,那么就会降低自动化脚本的稳定性,设置元素等待可改善这种问题造成的不稳定。
Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待。
隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。
显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了。
from selenium import webdriver
from selenium.webdriver.common.by import By
# WebDriverWait 库,负责循环等待
from selenium.webdriver.support.ui import WebDriverWait
# expected_conditions 类,负责条件出发
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
# 页面一直循环,直到 id="myDynamicElement" 出现
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
#显示等待
element = WebDriverWait(driver,5,0.5).until(
EC.presence_of_all_elements_located((By.ID,"kw"))
)
driver.find_element_by_id("kw").send_keys("selenium")
#找到id 为dropdown1的父元素
#is_displayed():该元素是否用户可以见
WebDriverWait(dr, 10).until(lambda the_driver: the_driver.find_element_by_id('dropdown1').is_displayed())
# 退出driver
driver.quit()
如果不写参数,程序默认会 0.5s 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回。
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions).until()
WebDriverWait()一般由until()或until_not()方法配合使用,下面是方法说明
下面是一些内置的等待条件,你可以直接调用这些条件,而不用自己写某些等待条件了。
title_is
title_contains
presence_of_element_located
visibility_of_element_located
visibility_of
presence_of_all_elements_located
text_to_be_present_in_element
text_to_be_present_in_element_value
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
element_to_be_clickable – it is Displayed and Enabled.
staleness_of
element_to_be_selected
element_located_to_be_selected
element_selection_state_to_be
element_located_selection_state_to_be
alert_is_present
方法:implicitly_wait(wait_time)
实例:driver.implicitly_wait(30)
通过一定的时长等待页面上某元素加载完成,如果超出了设置的时长元素还没有被加载,则抛出NoSuchElementException异常,WebDriver
隐式等待比较简单,提供了implicitly_wait()方法来实现隐式等待,默认设置为0,单位为秒。
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://www.xxxxx.com/loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")
在脚本执行中固定休眠
import time
time.sleep(1)
方法:get(url)
实例:driver.get(“http//:www.baidu.com”)
方法:current_url
实例:driver.current_url
实例:driver.page_source
page_source属性,但是那个是获取整个网页的html而不是元素的html
通过 get_attribute(‘innerHTML’)的方式可以获取某个元素的html信息
实例:driver.find_element_by_id(‘tb-37327761306’).get_attribute(‘innerHTML’)
方法:close()
实例:driver.close()
close()方法只是关闭页面,但如果只有一个页面被打开,close()方法同样会退出浏览器
方法:quit()
实例:driver.quit()
方法:maximize_window()
实例:driver.maximize_window()
方法:name
实例:drvier.name
方法:forward()
实例:driver.forward()
方法:back()
实例:driver.back()
方法:get_screenshot_as_file(filename)
实例:driver.get_screenshot_as_file(“D:\Program Files\Python27\NM.bmp”)
方法:is_selected()
实例:driver.find_element_by_id(“form1”).is_selected()
方法:is_displayed()
实例:driver.find_element_by_id(“iptPassword”).is_displayed()
方法:is_enabled()
实例:driver.find_element_by_id(“iptPassword”).is_enabled()
方法:send_keys(*values)
实例:driver.find_element_by_id(“iptUsername”).send_keys(‘admin’)
注意如果是函数需要增加转义符u,eg.
driver.find_element_by_id(“iptUsername”).send_keys(u’青春’)
from selenium.webdriver.common.keys import Keys
driver.find_element_by_xpath("//*[@id='gxszButton']/a[1]").send_keys(Keys.ENTER) #键盘输入enter
# driver.find_element_by_xpath("//*[@id='gxszButton']/a[1]").click() #用click()点__击
当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示或者获取提示信息方法如下:
alert = driver.switch_to_alert()
# 点击接受弹窗
driver.switch_to.alert.accept()
这将返回当前打开的警报对象。有了这个对象,你现在可以接受,拒绝,读取其内容,甚至类型会得到一个提示。这个接口同样适用警告,确认和提示。参考到的JavaDoc 或RubyDocs的更多信息。
一个浏览器肯定会有很多窗口,所以我们肯定要有方法来实现窗口的切换。
切换窗口的方法如下:
driver.switch_to.window("this is window name")
driver.switch_to_window("windowName")
也可以使用 window_handles 方法来获取每个窗口的操作对象。例如:
for handle in driver.window_handles:
driver.switch_to_window(handle)
从frames到frames(或到iframe中):
driver.switch_to_frame("frameName")
访问子frames由一个圆点分隔的路径,并且可以通过其索引指定frames。是:
driver.switch_to_frame("frameName.0.child")
你可以执行任意javascript来找到一个元素,只要你返回一个DOM元素,它将自动转换为一个WebElement对象。
简单的例子,在页面上加载了jQuery:
element = driver.execute_script("return $('.cheese')[0]")
在页面上的每一个标签查找所有输入元素:
labels = driver.find_elements_by_tag_name("label")
inputs = driver.execute_script(
"var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
"inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels)
from selenium import webdriver
# 模拟手机
mobilesetting = {"deviceName":"iPhone 6 Plus"}
options = webdriver.ChromeOptions()
options.add_experimental_option("mobileEmulation", mobilesetting)
driver = webdriver.Chrome(chrome_options=options)
# 设置大小
driver.set_window_size(400, 800)
# driver.maximize_window()
driver.get("https://www.taobao.com")
# 后退
driver.back()
# 前进
driver.forward()
# 刷新
driver.refresh()
示例演示:
# 导入 webdriver
from selenium import webdriver
# 要想调用键盘按键操作需要引入keys包
from selenium.webdriver.common.keys import Keys
# 创建chrome启动选项
chrome_options = webdriver.ChromeOptions()
# 指定chrome启动类型为headless 并且禁用gpu
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
# 调用环境变量指定的chrome浏览器创建浏览器对象
driver = webdriver.Chrome(chrome_options=chrome_options)
# 如果没有在环境变量指定Chrome位置
# driver = webdriver.Chrome(chrome_options=chrome_options, executable_path='/home/wx/application/chromedriver')
# get方法会一直等到页面被完全加载,然后才会继续程序,通常测试会在这里选择 time.sleep(2)
driver.get("http://www.baidu.com/")
# 获取页面名为 wrapper的id标签的文本内容
data = driver.find_element_by_id("wrapper").text
# 打印数据内容
print data
# 打印页面标题 "百度一下,你就知道"
print driver.title
# 生成当前页面快照并保存
driver.save_screenshot("baidu.png")
# id="kw"是百度搜索输入框,输入字符串"长城",注意中文前面得加u将其变为原始字符串
driver.find_element_by_id("kw").send_keys(u"长城")
# id="su"是百度搜索按钮,click() 是模拟点击
driver.find_element_by_id("su").click()
# 获取新的页面快照
driver.save_screenshot("长城.png")
# 打印网页渲染后的源代码
print driver.page_source
# 获取当前页面Cookie
print driver.get_cookies()
# ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
# ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
# 输入框重新输入内容
driver.find_element_by_id("kw").send_keys("wangxin")
# 模拟Enter回车键
driver.find_element_by_id("su").send_keys(Keys.RETURN)
# 清除输入框内容
driver.find_element_by_id("kw").clear()
# 生成新的页面快照
driver.save_screenshot("王鑫.png")
# 获取当前url
print driver.current_url
# 关闭当前页面,如果只有一个页面,会关闭浏览器
driver.close()
参考:https://wangxin1248.github.io/python/2018/09/python3-spider-8.html
https://www.cnblogs.com/fnng/archive/2013/06/16/3138283.html
http://xianyucoder.cn/2018/12/29/learn-selenium/