python3 web测试模块selenium

selenium是一个用于web应用程序测试工具,selenium测试直接运行在浏览器中,就像真正的用户在操作一样,支持的浏览器包括IE(7,8,9,10,11),mozilla firefox,safari,google chrom,opera等,可使用java,python等多种语言编写用例脚本。

Selenium Python绑定提供了一个简单的API,可以使用Selenium WebDriver编写功能/验收测试。通过Selenium Python API,您可以直观地访问Selenium WebDriver的所有功能。

Selenium Python绑定提供了一个方便的API来访问Selenium WebDrivers,如Firefox,Ie,Chrome,Remote等。目前支持的Python版本是2.7,3.5及更高版本

1、selenium安装配置

pip安装:

pip install selenium

wheel安装:

#下载wheel安装文件:https://pypi.python.org/pypi/selenium/#downloads
pip install selenium-3.13.0-py2.py3-none-any.whl

chrome浏览器支持的chromeDriver驱动配置:

注意:此前必须安装好chrome浏览器

chromedriver下载地址:https://sites.google.com/a/chromium.org/chromedriver/downloads

首先查看chrome浏览器版本,然后选定支持浏览器版本的chromDriver选择适合的平台包进行下载,下载完后需要配置环境:

在windows系统中可以将chromedriver.exe文件直接拖到python的scripts目录中即可,也可以将路径加入到环境变量中。

在linux下需要将可执行文件配置到环境变量或将文件移动到属于环境变量的目录中

验证安装是否成功,可执行命令chromedriver,如果可以看到chromeDriver的版本号说明安装成功

使用python脚本测试:

from selenium import webdriver

browser=webdriver.Chrome()

#如果能弹出一个空白的chrome浏览器页面,说明配置成功

其他浏览器的驱动安装配置一样,附上其他浏览器的驱动下载链接地址:

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/

我们还可以使用phantomJS一个无界面的webkit浏览器引擎,它原生支持多种web标准:DOM操作,CSS选择器,JSON,Canvas以及SVG

下载地址:http://phantomjs.org/download.html

下载完成后,将PhantomJS可执行文件所在的路径配置到环境变量中,如在windows下降下载的文件解压之后打开会看到一个bin文件夹,里面包含一个可执行文件phantomjs.exe,我们需要将它直接放在配置好的环境变量路径下或者将它所在的路径配置到环境变量里,或直接将它复制到python的scripts文件夹下

测试安装:

(virtualenv-36) C:\Users\Administrator\PycharmProjects\untitled\pachong>phantomjs -v
2.1.1
#在python的terminal环境下执行命令phantomjs -v,如果能打印版本信息说明安装成功

Selenium支持PhantomJS,不过phantomJS官方说明已不再更新了,在selenium中使用phantomJS将弹出警告信息,建议使用chrome或firefox无头版,下面将重点介绍chrome和firefox

2、Selenium的基本使用

(1)声明浏览器对象

Selenium支持很多浏览器包括chrome、Firefox、Edge、Safari等,各浏览器初始化对象方法:

from selenium import webdriver

#browser=webdriver.Firefox()
browser=webdriver.Chrome()
#browser=webdriver.Edge()
#browser=webdriver.Safari()

print(type(browser))

#返回的是一个WebDriver对象
<class 'selenium.webdriver.chrome.webdriver.WebDriver'>

WebDriver对象的方法和属性:(获取节点方法在后续介绍)

  • add_cookie(cookie_dict):  为当前会话添加一个cookie,为字典类型
  • back():    在浏览器历史记录中后退一步
  • forward(): 在浏览器历史上前进一步
  • close():    关闭当前窗口
  • create_web_element(element_id):  使用指定的id创建Web元素
  • delete_all_cookies():  删除会话范围内的所有cookie
  • delete_cookie(name): 删除具有给定名称的单个cookie
  • execute(driver_command,params=None):  发送command执行的命令
  • execute_async_script(script,*args):  异步执行当前窗口或框架中的JavaScript
  • execute_script(script,*args):  同步执行当前窗口或框架中的JavaScript
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.execute_script("alert('are you sure');")

#它基本可以实现JavaScript的所有功能
  • fullscreen_window():调用窗口管理器特定的全屏操作
  • get(url):在当前浏览器会话中加载网页
  • get_cookie(name):按名称获取单个cookie
  • get_cookies():返回一组字典的cookies
  • get_log(log_type):获取给定日志类型的日志
  • get_screenshot_as_base64():获取当前窗口的屏幕截图,作为base64编码的字符串
  • get_screenshot_as_file(filename):将当前窗口中的截屏保存为png图形
  • get_screenshot_as_png():获取当前窗口的屏幕截图作为二进制数据
  • get_window_position(windowhandle='current'):获取当前窗口的x,y位置
  • get_window_rect():获取窗口的x,y坐标以及当前窗口的高度和宽度
  • get_window_size():获取当前窗口的高度和宽度
  • maximize_window():最大化webdriver正在使用的当前窗口
  • minimize_window():最小化当前webdricer使用窗口
  • quit():退出驱动程序并关闭每个关联的窗口
  • refresh():刷新当前页面
  • save_screenshot(filename):将当前窗口的屏幕截图保存为PNG图形文件
  • set_page_load_timeout(time_to_wait):设置等待页面加载完成的时间
  • set_script_timeout(time_to_wait):设置脚本在执行期间等待的时间
  • set_window_position(x,y,windowHandle='current'):设置当前窗口的x,y位置
  • set_window_rect(x=None,y=None,width=None,height=None):设置窗口的x,y坐标以及当前窗口的高度和宽度
  • set_window_size(width,height,windowHandle='current'):设置当前窗口的高度和宽度
  • current_url:获取当前页面的URL
  • current_window_handle:返回当前窗口的句柄
  • desired_capabilities:返回驱动程序当前使用的所需功能
  • log_types:获取可用日志类型的列表
  • name:返回此实例的基础浏览器的名称
  • page_source:获取当前页面的源码
  • switch_to:将焦点切换到所有选项的对象上driver.switch_to.alert
  • title:返回当前页面的标题
  • window_handles:返回当前会话中所有窗口的句柄
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('http://selenium-python.readthedocs.io')
browser.execute_script('window.open("https://www.baidu.com");')  #在标签页打开URL
browser.execute_script('window.open("https://www.taobao.com");')

browser.back()  #后退到前一个页面
browser.set_page_load_timeout(5)
browser.forward()  #前进到下一个页面
print(browser.name)
print(browser.title)
print(browser.current_url)
print(browser.current_window_handle)
print(browser.get_cookies())
print(type(browser))

#
chrome
Selenium with Python — Selenium Python Bindings 2 documentation
http://selenium-python.readthedocs.io/
CDwindow-243FD31239F20FCC0195DD522A60A0DA
[{'domain': '.readthedocs.io', 'expiry': 1530766561, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False, 'value': 'GA1.2.1126774326.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1593752161, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False, 'value': 'GA1.2.2096958532.1530680157'}, {'domain': '.readthedocs.io', 'expiry': 1530680217, 'httpOnly': False, 'name': '_gat_rtfd', 'path': '/', 'secure': False, 'value': '1'}]
<class 'selenium.webdriver.chrome.webdriver.WebDriver'>

获取页面截图:

from selenium import webdriver

driver=webdriver.Chrome()
driver.get('http://www.python.org')
driver.save_screenshot('screenshot.png')  #保持页面截图到当前路径
driver.quit()

将页面滚动到底部:

from selenium import webdriver
driver=webdriver.Chrome()
driver.get('http://www.python.org')
#通过DOM中的window对象的scrollTo方法,将窗口位置滚动到指定位置,document.body.scrollHeight返回整个body的高度,所以页面将滚动到页面底部
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")

cookies操作:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 16:19
# @Author  : Py.qi
# @File    : test7.py
# @Software: PyCharm
from selenium import webdriver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
print(driver.get_cookies())   #获取所有cookies
driver.add_cookie({'name':'name','domain':'www.baidu.com','value':'germey'})   #添加cookie
print(driver.get_cookies())
driver.delete_all_cookies()
print(driver.get_cookies())

(2)定位元素

class selenium.webdriver.common.by.By
有各种策略来定位页面中的元素。你可以使用最适合你的情况。Selenium提供了以下方法来定位页面中的元素:

find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
要查找多个元素(这些方法将返回一个列表):

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
除了上面给出的公共方法之外,还有两个私有方法可能对页面对象中的定位器有用。这些是两个私有方法:find_element和find_elements

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/4 13:03
# @Author  : Py.qi
# @File    : test2.py
# @Software: PyCharm
from selenium import webdriver
from selenium.webdriver.common.by import By
driver=webdriver.Chrome()
driver.get('http://selenium-python.readthedocs.io/locating-elements.html#locating-elements')
data=driver.find_element(By.CLASS_NAME,'simple')
#driver.find_element(By.ID,'IDname') #获取ID标签定位元素
#driver.find_element(By.CSS_SELECTOR,'cssname')#CSS选择器定位元素
#driver.find_element(By.LINK_TEXT,'linktext') #链接文本定位元素
#driver.find_element(By.PARTIAL_LINK_TEXT,'linktext') #部分链接文件定位元素
#driver.find_element(By.NAME,'name') #属性名定位元素
#driver.find_element(By.TAG_NAME,'tagname') #标签名定位元素

print(data.text)  #打印元素文本内容

#
find_element_by_id
find_element_by_name
find_element_by_xpath
find_element_by_link_text
find_element_by_partial_link_text
find_element_by_tag_name
find_element_by_class_name
find_element_by_css_selector
#如获取多个,可是使用:
data=driver.find_elements(By.CLASS_NAME,'simple')

除了使用上面的方法外,还可以使用更细致的方法定位元素:

通过Id定位:
当您知道元素的id属性时使用此选项。使用此策略,将返回id属性值与该位置匹配的第一个元素,如使用find_elements_by_id将返回多个匹配的元素。如果没有元素具有匹配的id 属性,NoSuchElementException则会引发

driver.find_element_by_id('idname')
driver.find_elements_by_id('idname')

按名称定位:
当您知道元素的name属性时,请使用此选项。使用此策略,将返回名称属性值与位置匹配的第一个元素,如使用find_elements_by_name将返回多个匹配的元素。如果没有元素具有匹配的name 属性,NoSuchElementException则将引发

driver.find_element_by_name('name')
driver.find_elements_by_name('name')

通过XPath定位:
XPath是用于在XML文档中定位节点的语言。由于HTML可以是XML(XHTML)的实现,因此Selenium用户可以利用这种强大的语言来定位其Web应用程序中的元素。XPath扩展了通过id或name属性定位的简单方法,并打开了各种新的可能性,例如在页面上查找第三个复选框。

使用XPath的主要原因之一是当您没有适合您要查找的元素的id或name属性时。您可以使用XPath以绝对术语或相对于具有id或name属性的元素来定位元素。XPath定位器也可以用来通过id和name之外的属性指定元素。

XPaths包含根(html)中所有元素的位置,因此可能会失败,只需对应用程序进行最轻微的调整。通过查找具有id或name属性的附近元素(理想情况下是父元素),可以根据关系找到目标元素。这不太可能改变,可以使您的测试更加健壮

driver.find_element_by_xpath("//from[1]")  #查看第一个表单元素
friver.dind_element_by_xpath("//from[@id='loginform']")  #查找id为loinform的表单元素

通过链接文本查找超链接:
当您知道锚标记中使用的链接文本时,请使用此选项。使用此策略,将返回链接文本值与位置匹配的第一个元素。如果没有元素具有匹配的链接文本属性,NoSuchElementException则将引发

<HTML>
 <BODY>
  <p>你确定要这么做吗?</ p>
  <a href="continue.html">继续</a>
  <a href="cancel.html">取消</a>
</ BODY>
<HTML>


driver.find_element_by_link_text('继续)  #通过链接文本定位到元素

按标签名称定位元素:
如果要按标签名称查找元素,请使用此选项。使用此策略,将返回具有给定标记名称的第一个元素。如果没有元素具有匹配的标记名称,NoSuchElementException 则将引发

driver.find_element_by_tag_name('h1')

按类名定位元素:
如果要按类属性名称定位元素,请使用此选项。使用此策略,将返回具有匹配类属性名称的第一个元素。如果没有元素具有匹配的类属性名称,NoSuchElementException则将引发

driver.find_element_by_class_name('content')

通过CSS选择器定位元素:
当你想通过CSS选择器语法找到一个元素时使用它。使用此策略,将返回具有匹配的CSS选择器的第一个元素。如果没有元素具有匹配的CSS选择器,NoSuchElementException则会引发

driver.find_element_by_css_selector('p.content')

(3)元素对象(element)

当我们通过上面 的方法定位到元素后返回的对象称为web元素对象,我们可以对元素对象再进行交互或继续查找等操作

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/4 13:55
# @Author  : Py.qi
# @File    : test3.py
# @Software: PyCharm
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
opt=Options()
opt.add_argument('headless')
driver=webdriver.Chrome(chrome_options=opt)
driver.get('http://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement')
element=driver.find_element_by_id('module-selenium.webdriver.remote.webelement')
print(element)
print(type(element))

#返回一个webelement对象
<selenium.webdriver.remote.webelement.WebElement (session="dfaee65201abdf5a931306df6e7fe421", element="0.95256057244967-1")>
<class 'selenium.webdriver.remote.webelement.WebElement'>
  • selenium.webdriver.remote.webelement.WebElement为一个DOM元素,它的方法和属性包括:
  • clear() :清除文本元素
  • click() :单击元素按钮
  • get_attribute(name) :获取元素的给定属性的属性值
  • get_property(name) :获取元素的给定属性
  • is_displayed() :判断元素是否存在
  • is_enable() :判断元素是否被启用
  • is_selected() :返回元素是否被选中
  • screenshot(filename) :将当前元素的屏幕截图保存到文件
  • send_keys() #发送元素值
  • submit() :提交表单
  • value_of_css_property() :CSS属性的值
  • id :selenium使用的内部ID
  • location :元素在可渲染画布中的位置
  • location_once_scrolled_into_view :发现元素在屏幕视图中的位置
  • rect :返回包含元素大小和位置的字典
  • screenshot_as_base64 :获取当前元素的截屏,作为base64编码的字符串
  • size :获取元素的大小
  • tag_name :获取元素的tagName属性
  • text :获取元素的文本
与页面交互,实现输出文本搜索功能,并打印搜索结果源码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/4 13:55
# @Author  : Py.qi
# @File    : test3.py
# @Software: PyCharm
from selenium import webdriver

driver=webdriver.Chrome()
driver.get('http://www.cnblogs.com/zhangxinqi/')
element=driver.find_element_by_id('q')  #获取输入框元素
element.send_keys('python3之requests')  #发送元素
button=driver.find_element_by_id('btnZzk')  #获取搜索按钮
button.click()  #发送搜索动作
data=driver.page_source   

print(driver.current_url)   #打印URL
print(data)
print(type(element))
driver.close()

#
http://zzk-s.cnblogs.com/s?w=blog%3Azhangxinqi%20python3%E4%B9%8Brequests
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>
    <meta charset="utf-8" />
    <title> blog:zhangxinqi python3之requests - 博客园找找看</title>......

(4)动作链

class selenium.webdriver.common.action_chains.ActionChains(driver)

 在上面的实例中我们针对的是某个节点元素的操作,如果要对没有特定元素的对象操作如鼠标拖拽、键盘按键等,这些动作就称为动作链,selenium使用ActionChains()类来实现鼠标移动,鼠标按钮操作,按键操作和上下文菜单交互,悬停和拖放等

  • click(on_element=None) ——单击鼠标左键
  • click_and_hold(on_element=None) ——点击鼠标左键,不松开
  • context_click(on_element=None) ——点击鼠标右键
  • double_click(on_element=None) ——双击鼠标左键
  • drag_and_drop(source, target) ——拖拽到某个元素然后松开
  • drag_and_drop_by_offset(source, xoffset, yoffset) ——拖拽到某个坐标然后松开
  • key_down(value, element=None) ——按下某个键盘上的键
  • key_up(value, element=None) ——松开某个键
  • move_by_offset(xoffset, yoffset) ——鼠标从当前位置移动到某个坐标
  • move_to_element(to_element) ——鼠标移动到某个元素
  • move_to_element_with_offset(to_element, xoffset, yoffset) ——移动到距某个元素(左上角坐标)多少距离的位置
  • perform() ——执行链中的所有动作
  • release(on_element=None) ——在某个元素位置松开鼠标左键
  • send_keys(*keys_to_send) ——发送某个键到当前焦点的元素
  • send_keys_to_element(element, *keys_to_send) ——发送某个键到指定元素

将元素拖拽到目标位置:

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()

执行鼠标操作的流程:

menu = driver.find_element_by_css_selector(".nav") #获取element对象
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")  #获取点击对象
#创建鼠标对象
actions = ActionChains(driver)
#移动鼠标到对象
actions.move_to_element(menu)
#点击对象
actions.click(hidden_submenu)
#执行操作
actions.perform()

(5)弹出对话框

class selenium.webdriver.common.alert.Alert(driver)

Alert内置支持处理弹窗对话框,方法:

  • accept()  :确认弹窗,用法:Alert(driver).appept()
  • authenticate(username,password) :将用户名和密码发送到authenticated对话框,隐含点击确定,用法:driver.switch_to.alert.authenticate('username','password')
  • dismiss() :取消确认
  • send_keys(keysToSend) :将密钥发送到警报,keysToSend为要发送的文本
  • text :获取Alert的文本
import time
from selenium import webdriver
from selenium.webdriver.common.alert import Alert
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
driver.execute_script("alert('确定');")  #弹出窗口
time.sleep(2)
print(driver.switch_to.alert.text) #获取alert文本
alert=Alert(driver).accept()  #自动点击确定窗口

(6)键盘操作

class selenium.webdriver.common.keys.Keys

selenium提供一个keys包来模拟所有的按键操作,下面我们介绍下一些常用的按键操作:

  • 回车键:Keys.ENTER
  • 删除键:Keys.BACK_SPACE
  • 空格键:Keys.SPACE
  • 制表键:Keys.TAB
  • 回退键:Keys.ESCAPE
  • 刷新键:Keys.F5
  • 全选(ctrl+A):send_keys(Keys.CONTROL,'a')   #组合键需要用send_keys方法操作
  • 复制(ctrl+C):send_keys(Keys.CONTROL,'c')
  • 剪切(ctrl+X):send_keys(Keys.CONTROL,'x')
  • 粘贴(ctrl+V):send_keys(Keys.CONTROL,'v')

实现点击页面从python的pypi页面下载selenium源码包:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 13:05
# @Author  : Py.qi
# @File    : test5.py
# @Software: PyCharm
import requests
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
driver=webdriver.Chrome()
driver.get('https://pypi.org/')

element=driver.find_element_by_id('search')  #获取输入框
element.send_keys('selenium')  #搜索selenium包
element.send_keys(Keys.ENTER)  #按回车键

element_a=driver.find_element_by_link_text('selenium') #定位selenium包链接

ActionChains(driver).move_to_element(element_a).click(element_a).perform() #按左键点击链接执行

element_down=driver.find_element_by_link_text('Download files')  #定位下载链接
ActionChains(driver).move_to_element(element_down).click(element_down).perform()  #按左键点击链接

element_selenium=driver.find_element_by_link_text('selenium-3.13.0.tar.gz')  #定位元素selenium下载包链接
data=element_selenium.get_attribute('href')   #获取链接地址
with open('selenium-3.13.0.tar.gz','wb') as f:
    source=requests.get(data).content   #请求下载链接地址获取二进制包数据
    f.write(source)  #写入数据
    f.close()
    
driver.quit()

(7)延时等待

目前,大多数Web应用程序都在使用AJAX技术。当浏览器加载页面时,该页面中的元素可能以不同的时间间隔加载。这使定位元素变得困难:如果DOM中尚未存在元素,则locate函数将引发ElementNotVisibleException异常。使用等待,我们可以解决这个问题。等待在执行的操作之间提供了一些松弛 - 主要是使用元素定位元素或任何其他操作。

Selenium Webdriver提供两种类型的等待 - 隐式和显式。显式等待使WebDriver等待某个条件发生,然后再继续执行。在尝试查找元素时,隐式等待会使WebDriver轮询DOM一段时间。

显示等待:

显示等待是根据定义的代码,用于在进一步执行代码之前等待某个条件发送,它提供了一些便捷方法,可以编写在仅需要等待的代码上,实现方法需要WebDriverWait与ExpectedCondition结合使用:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 14:41
# @Author  : Py.qi
# @File    : test6.py
# @Software: PyCharm
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()
driver.get('https://www.taobao.com/')
wait=WebDriverWait(driver,3)  #设置监听driver等待时间3秒
input=wait.until(EC.presence_of_element_located((By.ID,'q'))) #设置等待条件为id为q的元素加载完成
button=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search')))  #设置等待条件为class名为btn-search的元素加载完成
print(input,button)

其他等待条件:

  • title_is :标题是某内容
  • title_contains :标题包含某内容
  • presence_of_element_located :节点加载出来,传入定位元组,如(By.ID, 'p')
  • 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 :节点可点击
  • staleness_of :判断一个节点是否仍在DOM,可判断页面是否已经刷新
  • element_to_be_selected :节点可选择,传节点对象
  • element_located_to_be_selected :节点可选择,传入定位元组
  • element_selection_state_to_be :传入节点对象以及状态,相等返回True,否则返回False
  • element_located_selection_state_to_be :传入定位元组以及状态,相等返回True,否则返回False
  • alert_is_present :是否出现警告

隐式等待:

当使用隐式等待执行测试的时候,如果Selenium没有在DOM中找到节点,将继续等待,超出设定时间后,则抛出找不到节点的异常。换句话说,当查找节点而节点并没有立即出现的时候,隐式等待将等待一段时间再查找DOM,默认的时间是0,调用driver的implicitly_wait()方法实现隐式等待:

from selenium import webdriver

driver = webdriver.Firefox()
driver.implicitly_wait(10) #隐式等待设置为10等待时间
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

(8)异常处理

所有webdriver代码中发生的异常:

  • selenium.common.exceptions.WebDriverException  :webdriver基本异常
  • selenium.common.exceptions.UnknownMethodException  :请求的命名与URL匹配但该URL方法不匹配
  • selenium.common.exceptions.UnexpectedTagNameException :当支持类没有获得预期的Web元素时抛出
  • selenium.common.exceptions.UnexpectedAlertPresentException :出现意外警报时抛出,通常在预期模式阻止webdriver表单执行任何更多命令时引发
  • selenium.common.exceptions.UnableToSetCookieException :当驱动程序无法设置cookie时抛出
  • selenium.common.exceptions.TimeoutException :当命令没有在足够的时间内完成时抛出
  • selenium.common.exceptions.StaleElementReferenceException :当对元素的引用现在“陈旧”时抛出,陈旧意味着该元素不再出现在页面的DOM上
  • selenium.common.exceptions.SessionNotCreatedException :无法创建新会话
  • selenium.common.exceptions.ScreenshotException :屏幕截图错误异常
  • selenium.common.exceptions.NoSuchWindowException :当不存在要切换的窗口目标时抛出
  • selenium.common.exceptions.NoSuchElementException :无法找到元素时抛出
  • selenium.common.exceptions.NoSuchCookieException :在当前浏览上下文的活动文档的关联cookie中找不到与给定路径名匹配的cookie
  • selenium.common.exceptions.NoSuchAttributeException :无法找到元素的属性时抛出
  • selenium.common.exceptions.JavascriptException :执行用户提供的JavaScript时发生错误
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/5 16:19
# @Author  : Py.qi
# @File    : test7.py
# @Software: PyCharm
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
driver=webdriver.Chrome()
driver.get('https://www.baidu.com')
try:
    element=driver.find_element_by_id('test')
    print(element)
except NoSuchElementException as e:
    print('元素不存在:',e)

#
元素不存在: Message: no such element: Unable to locate element: {"method":"id","selector":"test"}
  (Session info: chrome=67.0.3396.99)
  (Driver info: chromedriver=2.40.565498 (ea082db3280dd6843ebfb08a625e3eb905c4f5ab),platform=Windows NT 10.0.10240 x86_64)

(9)实例:抓取淘宝页面商品信息

#!/usr/bin/env python
#coding:utf-8
import re
import pymongo
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from urllib.parse import quote
from selenium.common.exceptions import WebDriverException
from pyquery import PyQuery as pq
#链接mongodb数据库
client=pymongo.MongoClient(host='localhost',port=27017)
db=client['taobao']
#定义无头chrome
opt=webdriver.ChromeOptions()
opt.add_argument('--headless')
driver=webdriver.Chrome(chrome_options=opt)
#定义页面等待时间
wait=WebDriverWait(driver,10)
#定义搜索商品名
uname='iPad'

#搜索商品
def search():
    try:
        url = 'https://s.taobao.com/search?q=' + quote(uname)
        driver.get(url)
        total=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.total')))
    except TimeoutException:
        return search()
    return total.text

#实现翻页商品
def next_page(page):
    print('正在抓取第{}'.format(page))
    try:
        if page >= 1:
            input=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input')))
            submit=wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit')))
            input.clear()
            input.send_keys(page)
            submit.click()
            wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > ul > li.item.active > span'),str(page)))
            wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))

            get_products()
    except TimeoutException:
        next_page(page)
    except WebDriverException as e:
        print('index_page:',e)

#解析商品信息
def get_products():
    #print('开始解析页面...')
    html = driver.page_source
    doc = pq(html, parser='html')
    items = doc('#mainsrp-itemlist .items .item').items()
    for i in items:
        product = {
            'image': 'https:' + i.find('.pic .img').attr('data-src'),
            'price': i.find('.price').text(),
            'deal': i.find('.deal-cnt').text(),
            'title': i.find('.title').text(),
            'shop': i.find('.shop').text(),
            'location': i.find('.location').text()
        }
        #print(product)
        save_to_mongo(product)

#保存到mongodb
def save_to_mongo(result):
    try:
        if db['collection_taobao'].insert(result):
            print('保存到mongodb成功!',result)
    except Exception:
        print('保存到mongodb失败',result)

#主函数调用
def main():
    try:
        total=search()
        total=int(re.compile('(\d+)').search(total).group(1))
        for i in range(1,total+1):
            next_page(i)
    finally:
        driver.quit()

#执行函数入口
if __name__ == '__main__':
    main()

抓取头条图片:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/7/6 11:16
# @Author  : Py.qi
# @File    : toutiao.py
# @Software: PyCharm
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import WebDriverException,TimeoutException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
import time
from PIL import Image
from io import BytesIO
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

opt=webdriver.ChromeOptions()
opt.add_argument('--headless')
driver=webdriver.Chrome(chrome_options=opt)
wait=WebDriverWait(driver,10)

def index_page(url,text):
    try:
        driver.get(url)
        insid=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#rightModule > div.search-wrapper > div > div > div.tt-input.tt-input-group.tt-input-group--append > input')))
        insid.clear()
        insid.send_keys(text)
        insid.send_keys(Keys.ENTER)
        driver.switch_to.window(driver.window_handles[1])
        images=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'body > div > div.y-box.container > div.y-left.index-middle > div.tabBar > ul > li:nth-child(3)')))
        ActionChains(driver).move_to_element(images).click(images).perform()
        element=driver.find_element_by_id('footer')
        sum=0
        while sum < 8:
            ActionChains(driver).move_to_element(element).send_keys(Keys.DOWN).perform()
            time.sleep(1)
            sum+=1
        html=driver.page_source
        doc=pq(html,parser='html')
        items=doc('.index-middle .feedBox .sections .articleCard').items()

        for i in items:
            #print(i('.title-box a').attr('href'))
            img_url='https://www.toutiao.com/a' + str(i('.title-box a').attr('href')).split('/')[-2]
            driver.get(img_url)
            if driver.title == '404错误页':
                continue
            else:
                wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.bui-box')))
                img_source=driver.page_source
                doc1=pq(img_source,parser='html')
                excent=doc1('.imageList .image-list .image-item').items()
                for item in excent:
                    image_url=item('.image-item-inner a').attr('href')
                    image_name='D:\images\\' + image_url.split('/')[-1] + '.jpg'
                    content=requests.get(image_url).content

                    im=Image.open(BytesIO(content))
                    im.save(image_name)

                    im.close()
                    print('保存图片成功',image_name)
    except TimeoutException:
        print('超时')
    except WebDriverException:
        print('driverError')
    except Exception as e:
        print(e)



def main():
    url='https://www.toutiao.com'
    context='街拍'
    index_page(url,context)



if __name__ == '__main__':
    main()
View Code

其他异常请查看官网文档:http://selenium-python.readthedocs.io/api.html#module-selenium.common.exceptions

其他详细使用方法参考官方文档:http://selenium-python.readthedocs.io

posted @ 2018-07-05 17:18  Py.qi  阅读(4548)  评论(0编辑  收藏  举报