本篇博客,我们将介绍selenium的使用。Selenium是一个自动化测试工具,支持多种浏览器,在爬虫程序中主要用来解决Javascript的渲染问题。
目录
1. 基本使用
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome() #浏览器驱动对象
try:
browser.get('https://www.baidu.com') #打开网址
input = browser.find_element_by_id('kw') #通过id查找元素 id="kw"
input.send_keys('Python') #向元素敲入Python
input.send_keys(Keys.ENTER) #敲回车
wait = WebDriverWait(browser, 10) #显示等待
wait.until(EC.presence_of_element_located((By.ID, 'content_left')))
print(browser.current_url) #请求url
print(browser.get_cookies())#获取cookie
print(browser.page_source) #获取网页源码(可以获取js渲染后的)
finally:
browser.close()
- 声明浏览器对象
from selenium import webdriver
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser = webdriver.Safari()
- 访问页面
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
print(browser.page_source)
browser.close()
2. 查找元素
- 查找单个元素
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_first = browser.find_element_by_id('q') #通过id获取元素 id="q"
input_second = browser.find_element_by_css_selector('#q') #通过css选择器获取元素 id="q"
input_third = browser.find_element_by_xpath('//*[@id="q"]')#通过xpath获取元素
print(input_first, input_second, input_third)
browser.close()
- 查找单个元素的其他方法
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input_first = browser.find_element(By.ID, 'q') #通用查找函数 find_element() 第一个参数是方式 如By.ID,By.xpath等
print(input_first)
browser.close()
- 查找多个元素
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
#查找多个元素 加s find_elements 函数接口和查找一个元素基本一致 就是加个s
#查找class="service-bd"的所有标签下的所有li标签
lis = browser.find_elements_by_css_selector('.service-bd li')
print(lis)
browser.close()
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
#也可以使用通用函数 find_elements() 第一个参数是方式 By.
lis = browser.find_elements(By.CSS_SELECTOR, '.service-bd li')
print(lis)
browser.close()
- 其他查找多个元素的函数
3. 元素交互操作
对获取的元素调用交互方法。
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('https://www.taobao.com')
input = browser.find_element_by_id('q')#通过id找到输入框 id="q"
input.send_keys('iPhone') #输入iPhone
time.sleep(1)
input.clear() #清空输入
input.send_keys('iPad') #输入iPad
button = browser.find_element_by_class_name('btn-search') #通过class name即class属性值 找到搜索按钮
button.click() #点击搜索按钮
- 交互动作
将动作附加到动作链中串行执行。
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult') #切换frame
#通过css选择器 获取元素 id="draggable"
source = browser.find_element_by_css_selector('#draggable')
target = browser.find_element_by_css_selector('#droppable')
actions = ActionChains(browser) #动作链
actions.drag_and_drop(source, target) #将source拖动到target
actions.perform() #执行
- 执行JavaScript
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
#有些动作没有api实现 可以通过执行js代码 来执行动作 比如进度条下拉
browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
browser.execute_script('alert("To Bottom")') #下拉完成后 出现提示框
4. 获取元素信息
- 获取属性
from selenium import webdriver
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
#id="zh-top-link-logo"的元素
logo = browser.find_element_by_id('zh-top-link-logo')
print(logo)
print(logo.get_attribute('class')) #获取元素的class属性值
- 获取文本值
from selenium import webdriver
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
#class="zu-top-add-question"的元素
input = browser.find_element_by_class_name('zu-top-add-question')
print(input.text) #获取元素文本值
- 获取ID、位置、标签名、大小
from selenium import webdriver
browser = webdriver.Chrome()
url = 'https://www.zhihu.com/explore'
browser.get(url)
input = browser.find_element_by_class_name('zu-top-add-question')
print(input.id)
print(input.location)
print(input.tag_name)
print(input.size)
5. Frame
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
#不能从父级frame中查找子级frame中的元素 必须切换到子级frame中
browser = webdriver.Chrome()
url = 'http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult') #切换到子级frame 传入子级frame元素的id属性值
source = browser.find_element_by_css_selector('#draggable')
print(source)
#也不能从子级frame中查找父级frame中的元素 必须切换回去
try:
logo = browser.find_element_by_class_name('logo')
except NoSuchElementException:
print('NO LOGO')
browser.switch_to.parent_frame()#切换到父级frame
logo = browser.find_element_by_class_name('logo')
print(logo)
print(logo.text)
6. 等待
selenium首先只能加载出一个整体框架,比如有一些ajax请求等,可能还没有立刻加载出来,所以可以添加等待,等页面完全加载出来后,再进行相应的操作。
- 隐式等待
当使用了隐式等待执行测试的时候,如果 WebDriver没有在 DOM中找到元素,将继续等待,超出设定时间后则抛出找不到元素的异常, 换句话说,当查找元素或元素并没有立即出现的时候,隐式等待将等待一段时间再查找 DOM,默认的时间是0。
from selenium import webdriver
#网速慢的时候 可以加隐式等待
browser = webdriver.Chrome()
browser.implicitly_wait(10)
browser.get('https://www.zhihu.com/explore')
input = browser.find_element_by_class_name('zu-top-add-question')
print(input)
- 显式等待
会有一个等待条件,和一个最长等待时间。在最长等待时间内,一直等待条件出现,如果没出现且超时了,就会报异常。
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
browser = webdriver.Chrome()
browser.get('https://www.taobao.com/')
wait = WebDriverWait(browser, 10)
input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
print(input, button)
等待条件:
7. 其他
- 前进后退
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
browser.get('https://www.taobao.com/')
browser.get('https://www.python.org/')
browser.back()
time.sleep(1)
browser.forward()
browser.close()
- cookies
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')
print(browser.get_cookies())#获取cookie
#添加cookie
browser.add_cookie({'name': 'name', 'domain': 'www.zhihu.com', 'value': 'germey'})
print(browser.get_cookies())
#删除所有cookie
browser.delete_all_cookies()
print(browser.get_cookies())
- 选项卡管理
import time
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
#执行js 新开一个选项卡
browser.execute_script('window.open()')
print(browser.window_handles) #返回所有选项卡的引用
#切换到第2个选项卡
browser.switch_to_window(browser.window_handles[1])
#访问淘宝
browser.get('https://www.taobao.com')
time.sleep(1)
#切换到第1个选项卡
browser.switch_to_window(browser.window_handles[0])
#访问python
browser.get('https://python.org')
- 异常处理
from selenium import webdriver
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.find_element_by_id('hello') #找不到元素
添加异常处理:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
browser = webdriver.Chrome()
try:
browser.get('https://www.baidu.com')
except TimeoutException:
print('Time Out')
try:
browser.find_element_by_id('hello')
except NoSuchElementException:
print('No Element')
finally:
browser.close()