一、简介
Selenium是一系列基于Web的自动化工具,提供一套测试函数,用于支持Web自动化测试。函数非常灵活,能够完成界面元素定位、窗口跳转、结果比较,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式堆动态渲染的页面非常有效,但同时爬取的速度回相应的下降
-
1、多浏览器支持
可以对多浏览器进行测试,如IE、Firefox、Safari、Chrome、Android手机浏览器等。 -
2、支持多种开发语言
Java、C#、Python、Ruby、PHP等。 -
3、支持多种操作系统
Windows、Linux、IOS、Android等。
二、准备工作
本文使用python和Chrome为例进行演示,python需要安装selenium库,还需要下载ChromeDriver,版本号要和Chrome版本号一致,不一致会报错
-
Chrome下载地址
http://npm.taobao.org/mirrors/chromedriver/
-
pythoon下载selenium
pip install selenium
三、常用用法
- 1、声名浏览器对象
from selenium import webdriver
driver = webdriver.Chrome()
# 这样就完成了浏览器对象的初始化并将其赋值为driver对象。接下来,我们要做的就是调用driver对象,让其执行各个动作以模拟浏览器操作。
- 2、访问页面
# 我们可以用get()方法来请求网页,参数传入链接URL即可
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 打印网页源码
print(driver.page_source)
# 关闭浏览器对象
driver.close()
- 3、查找元素
常用方法
# 通过元素id获取元素
find_element_by_id
# 通过元素name获取元素
find_element_by_name
# 通过xpath获取元素
find_element_by_xpath
# 通过a标签的文本值获取元素
find_element_by_link_text
# 匹配a标签的文本值获取元素
find_element_by_partial_link_text
# 通过标签名字获取元素
find_element_by_tag_name
# 通过类名获取元素
find_element_by_class_name
# 通过css选择器获取元素
find_element_by_css_selector
例子:如获取百度的输入输入框
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 通过id获取输入框
driver.find_element_by_id('kw')
# 通过元素name获取输入框
driver.find_element_by_name('wd')
print(driver.page_source)
driver.close()
查找多元素和单元素的方法大致是一样的
find_elements_by_id
find_elements_by_name
find_elements_by_xpath
find_elements_by_link_text
find_elements_by_partial_link_text
find_elements_by_tag_name
find_elements_by_class_name
find_elements_by_css_selector
- 4、元素交互
# Selenium可以驱动浏览器来执行一些操作,也就是说可以让浏览器模拟执行一些动作。
# 比较常见的用法有:输入文字时用send_keys()方法,清空文字时用clear()方法,点击按钮时用click()方法
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
input = driver.find_element_by_id('kw')
# 输入Python
input.send_keys('Python')
# 清空Python
input.clear()
time.sleep(1)
input.send_keys('Python')
# 点击“百度一下”按钮
driver.find_element_by_id('su').click()
print(driver.page_source)
driver.close()
- 5、执行JavaScript
# 对于某些操作,Selenium API并没有提供。比如,下拉进度条,它可以直接模拟运行JavaScript,
# 此时使用execute_script()方法即可实现
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 下拉到最底部
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
print(driver.page_source)
driver.close()
- 6、获取元素信息
# 我们可以使用get_attribute()方法来获取节点的属性,但是其前提是先选中这个节点
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
input = driver.find_element_by_id('kw')
# 获取元素的name属性
print(input.get_attribute('name'))
# 获取元素的id值
print(input.id)
# 获取元素的页面位置
print(input.location)
# 获取元素标签名字
print(input.tag_name)
# 获取元素的大小
print(input.size)
driver.close()
- 8、获取元素文本值
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
button = driver.find_element_by_id('su')
# 获取元素文本值
print(button.text)
print(driver.page_source)
driver.close()
- 9、切换Franme
# 网页中有一种元素叫作iframe,也就是子Frame,相当于页面的子页面,它的结构和外部网页的结构完全一致。
# Selenium打开页面后,它默认是在父级Frame里面操作,而此时如果页面中还有子Frame,它是不能获取到子Frame里面的节点的。
# 这时就需要使用switch_to.frame()方法来切换Frame
- 10、延时等待
# 在Selenium中,get()方法会在网页框架加载结束后结束执行,此时如果获取page_source,可能并不是浏览器完全加载完成的页面,
# 如果某些页面有额外的Ajax请求,我们在网页源代码中也不一定能成功获取到。所以,这里需要延时等待一定时间,确保节点已经加载出来。
# 这里等待的方式有两种:一种是隐式等待,一种是显式等待。
# 隐式等待
# 当使用隐式等待执行测试的时候,如果Selenium没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。
# 换句话说,当查找节点而节点并没有立即出现的时候,隐式等待将等待一段时间再查找DOM,默认的时间是0。
from selenium import webdriver
import time
driver = webdriver.Chrome()
# 用implicitly_wait()方法实现了隐式等待。
driver.implicitly_wait(10)
driver.get('https://www.baidu.com/')
input = driver.find_element_by_id('kw')
driver.close()
# 显式等待
# 隐式等待的效果其实并没有那么好,因为我们只规定了一个固定时间,而页面的加载时间会受到网络条件的影响。
# 这里还有一种更合适的显式等待方法,它指定要查找的节点,然后指定一个最长等待时间。
# 如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。
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
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 这里首先引入WebDriverWait这个对象,指定最长等待时间
wait = WebDriverWait(browser, 10)
# 用它的until()方法,传入要等待条件expected_conditions。
input = wait.until(EC.presence_of_element_located((By.ID, 'kw')))
driver.close()
- 11、前进和后退
# 平常使用浏览器时都有前进和后退功能,Selenium也可以完成这个操作,它使用back()方法后退,使用forward()方法前进。
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
driver.get('https://www.zhihu.com/')
driver.get('https://www.douban.com/')
# 后退
browser.back()
time.sleep(1)
# 前进
browser.forward()
browser.close()
- 12、cookies
# 使用Selenium,还可以方便地对Cookies进行操作,例如获取、添加、删除Cookies等。
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# 获取cookies
print(driver.get_cookies())
# 添加cookie
browser.add_cookie({'name': 'name', 'domain': 'www.baidu.com', 'value': 'hziwei'})
print(browser.get_cookies())
# 删除cookies
browser.delete_all_cookies()
print(browser.get_cookies())