selenium入门使用
[DeadPool爬虫]selenium入门使用
前一篇博客内容的代码中,已经使用了webdirver的功能,这个功能帮助我们在浏览器中打开网页,并且使我们能够对加载后的网页进行实时操作,这么神器的功能,来源于selenium这个框架,其实其本身定义是一个前端自动化测试框架,但是因为其特性,能够帮助我们很好的实现爬虫的功能,因此现在在爬虫领域其也是必须掌握的存在,接下来我就简单总结以下selenium的基础使用,高级使用同样需要在不断地编码中去掌握并同时查看其官方文档~
selenium 框架
Selenium 是 ThroughtWorks 一个强大的基于浏览器的开源自动化测试工具,它通常用来编写Web应用的自动化测试。
其本身就是一个独立的框架,拥有自己开的 IDE 工具,所以在爬虫领域里面通常是使用 selenium 中的webdirver模块来实现对浏览器的API调用。这里我们使用的就是 Python 的接口包
安装就也是简单的 pip install selenium
就可以了。
PS: 推荐大家使用virtualenv的方式
既然是用的是 selenium 中 webdirver 模块的功能,所以首先你需要在你的设备上拥有浏览器,同时下载该浏览器的对应驱动程序,这里不同的浏览器驱动不同,列举如下:
Chrome: https://sites.google.com/a/chromium.org/chromedriver/downloads Firefox: https://github.com/mozilla/geckodriver/releases Safari: https://webkit.org/blog/6900/webdriver-support-in-safari-10/ Edge: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
PS: 博文的最末附件会带上 chrome 的最新驱动(三个平台的)
selenium 上手
这里简单的 selenium 使用就以官方文档中的例子为基础,里面稍微修改了一点
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(executable_path="E:\\Github\\Lesson\\chromedriver.exe")
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()
这里与官方不同的是使用的 Chrome 作为浏览器,同时加载了驱动位置,其实很多博文和教程都是将驱动程序添加到了 windows 系统环境变量中,或者是放到了 selenium 安装的路径下,这里其实完全没有必要,因为只需要在加载的时候指定位置就行了,还方便根据不同的版本,来加载不同的驱动~
接下来简单解释一下上面的代码
===
这两个导包动作其实就是导入了selenium对应的webdirver模块和键盘绑定Keys,即你的回车、F1等
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
===
这就是我前面说的实例化webdriver的时候指定驱动目录就行了
driver = webdriver.Chrome(executable_path="E:\\Github\\Lesson\\chromedriver.exe")
===
打开页面访问指定网址,并同时判断网页打开是否正确(assert 断言,PS: Python test 中经常使用)
driver.get("http://www.python.org")
assert "Python" in driver.title
===
在当前页面找到name为q
的元素,其实就是python官网的搜索输入框,清除内容,填写内容,按下回车
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
===
判断当前页面内容里面是否存在指定字符串,然后关闭浏览器
assert "No results found." not in driver.page_source
driver.close()
PS: 一定要记得关闭浏览器,不然你会在不停的尝试中打开越来越多的浏览器
selenium 与页面交互
首先要对页面元素进行交互第一点就是定位元素位置,这里需要你有一定的html和css基础了,不过很好掌握。具体如何查找元素,总结如下:
# find a element
driver.find_element_by_id()
driver.find_element_by_name()
driver.find_element_by_xpath()
driver.find_element_by_link_text() # a 标签中的文本内容
driver.find_element_by_partial_link_text() # 非全匹配 a 标签中的文本内容
driver.find_element_by_tag_name()
driver.find_element_by_class_name()
driver.find_element_by_css_selector()
# 上面的方法可以统一为
driver.find_element(By.XPATH, '//button[text()="Some text"]')
# find the elements
driver.find_elements_by_id()
driver.find_elements_by_name()
driver.find_elements_by_xpath()
driver.find_elements_by_link_text() # a 标签中的文本内容
driver.find_elements_by_partial_link_text() # 非全匹配 a 标签中的文本内容
driver.find_elements_by_tag_name()
driver.find_elements_by_class_name()
driver.find_elements_by_css_selector()
# 上面的方法可以统一为
driver.find_elements(By.XPATH, '//button')
其中都很简单,主要比较特别的就是 XPath 这个东西了,不过也有其标准 W3C XPATH
然后元素找到了之后,怎么与之进行交互呢?其实简单想象一下,前端页面的交互主要分为两种形式:一种是输入;一种是点击。因此归纳的方式也就分为这两种
输入
例如下面这个密码输入框,可以通过下面的代码找到该输入框之后,清空内容,填写内容。
<input type="text" name="passwd" id="passwd-id" />
element = driver.find_element_by_id("passwd-id")
element = driver.find_element_by_name("passwd")
element = driver.find_element_by_xpath("//input[@id='passwd-id']")
element.clear()
element.send_keys("some text")
除了输入框,还有就是选择框,本质上任然是输入框,但是需要通过点击来实现的内容输入,这里我仍然建议以其HTML本身的含义来定义其类型,这是一种输入操作。
<select class="form-control" name="name">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
# 常规方法
# 选择全部的 options
element = driver.find_element_by_xpath("//select[@name='name']")
all_options = element.find_elements_by_tag_name("option")
for option in all_options:
print("Value is: %s" % option.get_attribute("value"))
option.click()
# Selenium 中的UI库 进行找寻select
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_xpath("//select[@name='name']"))
# 列举全部的options
options = select.options
# 选择特定的options
select.select_by_index(index)
select.select_by_visible_text("text")
select.select_by_value(value)
# 查看当前选中的options
selected_options = select.all_selected_options
# 选择全部的options
select.select_all()
# 重置全部的选择
select.deselect_all()
点击
对于点击事件,可以总结为两个方式: 1、点击动作直接完成;2、点击动作间隔完成。与之对应的就是点击和拖拽,其本质是一样的,只不过是点下和松开的时间间隔不同而已
针对点击直接完成(点击)
# 找到对应的button之后,直接触发点击事件即可
driver.find_element_by_id("submit").click()
针对点击间隔完成(拖拽)
# 找到目标元素和最终位置,执行拖拽效果
element = driver.find_element_by_name("source")
target = driver.find_element_by_name("target")
from selenium.webdriver import ActionChains
action_chains = ActionChains(driver)
action_chains.drag_and_drop(element, target).perform()
相比输入这个点击动作就要简单一些
selenium 附加功能
Popup dialogs
对于弹出的对话框支持
alert = driver.switch_to_alert()
history and location
浏览器的访问地址和历史
driver.get("http://www.example.com")
driver.forward()
driver.back()
windows and iframe
切换打开的窗口和嵌入的iframe
# 轮流切换当前打开的窗口
for handle in driver.window_handles:
driver.switch_to_window(handle)
# 切换当前的iframe
driver.switch_to_frame("frameName")
# 或者直接切换到里面的元素
driver.switch_to_frame("frameName.0.child")
# 回到默认窗口
driver.switch_to_default_content()
cookies
获取和增加当前域下的cookies
# Go to the correct domain
driver.get("http://www.example.com")
# Now set the cookie. This one's valid for the entire domain
cookie = {‘name’ : ‘foo’, ‘value’ : ‘bar’}
driver.add_cookie(cookie)
# And now output all the available cookies for the current URL
driver.get_cookies()
selenium 显式等待
简单来说就是判断你打开页面的过程中是否加载完成
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(executable_path="E:\\Github\\Lesson\\chromedriver.exe")
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
其中可以支持的触发动作包含一下方式:
wait.until(EC.title_is((By.ID, 'someid')))
wait.until(EC.title_contains((By.ID, 'someid')))
wait.until(EC.presence_of_element_located((By.ID, 'someid')))
wait.until(EC.visibility_of_element_located((By.ID, 'someid')))
wait.until(EC.visibility_of((By.ID, 'someid')))
wait.until(EC.presence_of_all_elements_located((By.ID, 'someid')))
wait.until(EC.text_to_be_present_in_element((By.ID, 'someid')))
wait.until(EC.text_to_be_present_in_element_value((By.ID, 'someid')))
wait.until(EC.invisibility_of_element_located((By.ID, 'someid')))
wait.until(frame_to_be_available_and_switch_to_it((By.ID, 'someid')))
wait.until(invisibility_of_element_located((By.ID, 'someid')))
wait.until(element_to_be_clickable((By.ID, 'someid')))
wait.until(staleness_of((By.ID, 'someid')))
wait.until(element_to_be_selected((By.ID, 'someid')))
wait.until(element_located_to_be_selected((By.ID, 'someid')))
wait.until(element_selection_state_to_be((By.ID, 'someid')))
wait.until(element_located_selection_state_to_be((By.ID, 'someid')))
wait.until(alert_is_present((By.ID, 'someid')))
以上,就是通过我自己对于selenium官方文档的知识总结,当然还有具体的高级使用方法,后续有机会的话,会将我遇到的一些问题挨个介绍一下~