zoukankan      html  css  js  c++  java
  • selenium webdrive使用

    一、selenium浏览器驱动的下载与调用

    1、安装三大浏览器驱动driver

    ①chrome的驱动chromedriver 下载地址:

    https://code.google.com/p/chromedriver/downloads/list

    http://chromedriver.storage.googleapis.com/index.html

    https://npm.taobao.org/mirrors/chromedriver/

    ②IE的驱动IEdriver 下载地址:

    http://www.nuget.org/packages/Selenium.WebDriver.IEDriver/

    http://selenium-release.storage.googleapis.com/index.html

    ③Firefox的驱动geckodriver

    selenium 3.0版本调用firefox的时候要用geckodriver.exe,selenium2无需驱动包。下载地址:

    https://github.com/mozilla/geckodriver/releases/

    ④其他浏览器驱动 :

    selenium还支持 Android(AndroidDriver)和 iPhone(IPhoneDriver) 的移动应用测试。

    https://www.npmjs.com/package/selenium-webdriver

    2、selenium 驱动ie 和 chrome 、Firefox的三种种方式:

    selenium驱动ie,chrome 的时候需要下载驱动 IEDriverServer、Chromedriver、geckodriver

    ①把 ie驱动、chrome驱动放在相应文件夹,在程序中添加路径即可:

    Chrome:
    System.setProperty(“webdriver.chrome.driver”,”D:Chromedriver.exe”);
    WebDriver driver = new ChromeDriver();

    IE:
    System.setProperty(“webdriver.ie.bin”,“D:IEDriverServer.exe”);
    WebDriver driver = new InternetExplorerDriver();

    ②直接把 ie驱动、chrome驱动放在Python根目录或其他目录下(只要该目录添加到了系统环境变最path下面即可),然后直接驱动

    ③将驱动放在各自浏览器的安装目录下,并设置用户环境变量

    将chromedriver.exe 放在chrome浏览器安装目录下(同时设置用户环境变量path:C:UsersxxxxxxAppDataLocalGoogleChromeApplication;)

    将IEDriverServer.exe 放在ie浏览器安装目录下(同时设置用户环境变量path:C:Program FilesInternet Explorer )

    调用ie浏览器时,要注意安全设置问题(internet选项–》安全 去掉“启用保护模式”的勾选)

    二、selenium 调用浏览器

    ①web自动化练习网站:
    http://sahitest.com/demo/index.htm

    ②调用chrome浏览器

     

    from selenium import webdriver
    
    driver=webdriver.Chrome() #调用chrome浏览器
    
    driver.get('https://www.baidu.com')
    
    print (driver.title)
    
    driver.quit()

    ③调用IE浏览器

    from selenium import webdriver
    
    driver=webdriver.Ie() #调用IE浏览器
    
    driver.get('https://www.baidu.com')
    
    print (driver.title)
    
    driver.quit()

    ③调用firefox浏览器

    from selenium import webdriver
    import time
    
    driver=webdriver.Firefox() #调用chrome浏览器
    
    driver.get('https://www.baidu.com')
    
    driver.find_element_by_id("kw").send_keys("Selenium2")
    
    driver.find_element_by_id("su").click()
    
    time.sleep(3) # 强制等待3秒再执行下一步, 强制等待,不管你浏览器是否加载完了
    
    driver.quit()

    三、Selenium的基本使用

    selenium下包含2个包,common和webdriver。
    common下仅有一个exceptions。selenium.common.exceptions所有selenium中可能发生的异常。
    其他操作及功能都在webdriver下。webdriver里除了common 和support ,其余的都是对应浏览器的方法/属性等。

    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对象的方法和属性:(browser=webdriver.Chrome()即browser的方法和属性)

    • back(): 在浏览器历史记录中后退一步

    • forward(): 在浏览器历史上前进一步

    • close(): 关闭当前窗口

    • quit():退出驱动程序并关闭每个关联的窗口

    • refresh():刷新当前页面

    • name:返回此实例的基础浏览器的名称

    • title:返回当前页面的标题

    • current_url:获取当前页面的URL

    • add_cookie(cookie_dict):为当前会话添加一个cookie,为字典类型

    • delete_all_cookies():删除会话范围内的所有cookie delete_cookie(name): 删除具有给定名称的单个cookie

    • get_cookie(name):按名称获取单个cookie get_cookies():返回一组字典的cookies

    • execute(driver_command,params=None): 发送command执行的命令

    • execute_async_script(script,*args):异步执行当前窗口或框架中的JavaScript,它不会阻塞主线程执行

    • execute_script(script,*args):同步执行当前窗口或框架中的JavaScript,用它执行js代码会阻塞主线程执行,直到js代码执行完毕

    • get(url):在当前浏览器会话中加载网页,一定要输入全部链接,包括“http://”,否则可能找不到

    • get_log(log_type):获取给定日志类型的日志

    • get_screenshot_as_base64():获取当前窗口的屏幕截图,作为base64编码的字符串

    • get_screenshot_as_file(filename):将当前窗口中的截屏保存为png图形

    • save_screenshot(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使用窗口

    • fullscreen_window():调用窗口管理器特定的全屏操作

    • set_window_rect(x=None,y=None,width=None,height=None):设置窗口的x,y坐标以及当前窗口的高度和宽度

    • set_window_size(width,height,windowHandle=‘current’):设置当前窗口的高度和宽度

    • set_window_position(x,y,windowHandle=‘current’):设置当前窗口的x,y位置

    • current_window_handle:返回当前窗口的句柄

    • window_handles:返回当前会话中所有窗口的句柄

    • create_web_element(element_id): 使用指定的id创建Web元素

    • set_page_load_timeout(time_to_wait):设置等待页面加载完成的时间

    • set_script_timeout(time_to_wait):设置脚本在执行期间等待的时间

    • desired_capabilities:返回驱动程序当前使用的所需功能

    • log_types:获取可用日志类型的列表

    • page_source:获取当前页面的源码

    • switch_to 将焦点切换到所有选项的对象上

    • switch_to.alert 返回浏览器的Alert对象,可对浏览器alert、confirm、prompt框操作

    • switch_to.default_content() 切到主文档

    • switch_to.frame(frame_reference) 切到某个frame

    • switch_to.parent_frame() 切到父frame,有多层frame的时候很有用

    • switch_to.window(window_name) 切到某个浏览器窗口

    • switch_to.active_element 返回当前焦点的WebElement对象,网页上当前操作的对象(也就是你网页上光标的位置),比如你鼠标点击到了一个input框,你可以在这个input框里输入信息,这时这个input框即焦点。

    实现JavaScript:

    from selenium import webdriver 
    
    driver=webdriver.Chrome() 
    
    driver.get('https://www.baidu.com') 
    
    driver.execute_script("alert('are you sure');") #它基本可以实现JavaScript的所有功能
    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))

    获取页面截图:

    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')
    #通过js中的window对象的scrollTo方法,将窗口位置滚动到指定位置,document.body.scrollHeight返回整个body的高度,所以页面将滚动到页面底部
    driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")

    cookies操作:

    #!/usr/bin/ python3
    # -*- coding: utf-8 -*-
    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、定位元素

    webdriver 提供了八种元素定位方法:

    1. id
    2. name
    3. class name
    4. tag name
    5. link text
    6. partial link text
    7. xpath
    8. css selector
    • find_element_by_id(id属性,可以唯一定位)
    • find_element_by_name (name属性,可以唯一定位)
    • find_element_by_xpath (最灵活,万能)
    • find_element_by_link_text (定位文字连接好用)
    • find_element_by_partial_link_text (定位文字连接好用)
    • find_element_by_tag_name (每个元素都会有tag标签,最不靠谱)
    • find_element_by_class_name (class属性定位元素)
    • find_element_by_css_selector (css选择器定位)

    有时候需要操作的元素是一个文字链接,那么我们可以通过link text 或partial link text 进行元素定位。也就是a标签
    比如,定位百度首页右上角的“新闻”,“hao123”,。。。。等等这些文字连接。就可以使用link text和partail link text定位方式
    通过linx text定位:

    find_element_by_link_text("新闻")
    find_element_by_link_text("贴吧")

    通过partail link text定位:

    find_element_by_link_text("")
    find_element_by_link_text("")

    要查找多个元素(这些方法将返回一个列表):

    • 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
    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_elements(By.CLASS_NAME,'simple') #获取多个
    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)  #打印元素文本内容

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

    driver.find_element_by_id('kw1')
    driver.find_elements_by_id('kw1')

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

    driver.find_element_by_name('wd')
    driver.find_elements_by_name('wd')

    按标签名称定位元素:
    如果要按标签名称查找元素,请使用此选项。使用此策略,将返回具有给定标记名称的第一个元素。如果没有元素具有匹配的标记名称则将引发NoSuchElementException异常。tag name 获取的是标签的名字,在一个页面上往往会有很多标签名相同的元素,这并不是说 tag name 方法就毫无用武之处,在定位一组元素的时候我们往往需要 tag name 方法来帮忙。

    driver.find_element_by_tag_name('input')

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

    driver.find_element_by_class_name('s_ipt')

    通过链接文本查找超链接:
    当操作的元素是一个文字链接, 那么我们可以通过link text 或 partial link text 进行元素定位。将返回链接文本值与位置匹配的第一个元素。如果没有元素具有匹配的链接文本属性,NoSuchElementException则将引发。当一个文字连接很长时,我们可以只取其中的一部分,只要取的部分可以唯一标识元素。一般一个页面上不会出现相同的文件链接,通过文字链接来定位元素也是一种简单有效的定位方式。

    在这里插入图片描述

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

    通过XPath定位:
    XPath是用于在XML文档中定位节点的语言。由于HTML可以是XML的实现,因此可以利用XPath来定位其Web应用程序中的元素。XPath扩展了通过id或name属性定位的方法,并打开了各种新的可能性,例如在页面上查找第三个复选框。使用XPath的主要原因之一是当您没有适合您要查找的元素的id或name属性时。您可以使用XPath以绝对术语或相对于具有id或name属性的元素来定位元素。XPath定位器也可以用来通过id和name之外的属性指定元素。

    绝对路径定位(定位最后一个元素):
    find_element_by_xpath("/html/body/div[2]/form/span/input")
    
    相对路径定位(定位最后一个元素):
    #通过自身的 id 属性定位
    find_element_by_xpath("//input[@id=’input’]")
    #通过上一级目录的 id 属性定位
    find_element_by_xpath("//span[@id=’input-container’]/input")
    #通过上三级目录的 id 属性定位
    find_element_by_xpath("//div[@id=’hd’]/form/span/input")
    #通过上三级目录的 name属性定位
    find_element_by_xpath("//div[@name=’q’]/form/span/input")

    当我们所要定位的元素很难找到合适的方式时,可以通这种绝对路径的方式位,缺点是当元素在很多级目录下时,我们不得不要写很长的路径,而且这种方式难以阅读和维护。 XPath 的定位方式非常灵活和强大的,而且 XPath 可以做布尔逻辑运算,例如://div[@id=’hd’ or @name=’q’]。

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

    xpath定位的缺点:
    1、性能差,定位元素的性能要比其它大多数方式差;
    2、不够健壮,XPath 会随着页面元素布局的改变而改变;
    3、兼容性不好,在不同的浏览器下对 XPath 的实现是不一样的。



    通过CSS选择器定位元素:
    CSS被用来描述 HTML 和 XML 文档的表现。CSS 使用选择器来为页面元素绑定属性。这些选择器可以被 selenium 用作定位。将返回具有匹配的CSS选择器的第一个元素。CSS 可以比较灵活选择控件的任意属性,一般情况下定位速度要比 XPath 快,但对于初学者来说比较难以学习使用。如果没有元素具有匹配的CSS选择器,NoSuchElementException则会引发

    driver.find_element_by_css_selector('p.content')

    在这里插入图片描述

    XPath、CSS定位速查表:

    CSS定位语法比 XPath 更为简洁,定位方式更多灵活多样;不过对 CSS 理解起来要比 XPath较难;但不管是从性能还是定位更复杂的元素上,CSS 优于XPath,所以更推荐使用 CSS定位页面元素。




    3、元素对象(element)

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

    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')
    element=driver.find_element_by_id('remote-webdriver-webelement') 
    print(element) 
    print(type(element))

    element的方法和属性包括:

    • 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 :获取元素的文本

    与页面交互,实现输出文本搜索功能,并打印搜索结果源码:

    from selenium import webdriver
    
    driver=webdriver.Chrome()
    driver.get('http://www.baidu.com')
    element=driver.find_element_by_id('xx')  #获取输入框元素
    element.send_keys('python')  #发送元素
    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()

    4、动作链

    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) ——发送某个键到指定元素

    将元素拖拽到目标位置:

    from selenium.webdriver import ActionChains
    element = driver.find_element_by_name("source")
    target = driver.find_element_by_name("target")
    action = ActionChains(driver)
    action.drag_and_drop(element, target).perform()

    执行鼠标操作的流程:

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

    (5)弹出对话框

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

    首先区别下alert、window和伪装对话框:

    alert,浏览器弹出框,一般是用来确认某些操作、输入简单的text或用户名、密码等,根据浏览器的不同,弹出框的样式也不一样,不过都是很简单的一个小框。在firebug中是无法获取到该框的元素的,也就是说alert是不属于网页DOM树的。如下图所示:

    window,浏览器窗口,点击一个链接之后可能会打开一个新的浏览器窗口,跟之前的窗口是平行关系(alert跟窗口是父子关系,或者叫从属关系,alert必须依托于某一个窗口),有自己的地址栏、最大化、最小化按钮等。这个很容易分辨。

    div伪装对话框,是通过网页元素伪装成对话框,这种对话框一般比较花哨,内容比较多,而且跟浏览器一看就不是一套,在网页中用firebug能够获取到其的元素,如下图:

    在这里插入图片描述

    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()  #自动点击确定窗口

    window操作
    window类似于alert,不过与原window是平行的,所以只需要切换到新的window上便可以操作该window的元素。driver.switch_to.window(window_handle)
    而window是通过window句柄handle来定位的。而selenium提供了两个属性方法来查询window句柄:driver.current_window_handle 和driver.window_handles
    用以上两个属性获取到当前窗口以及所有窗口的句柄,就可以切换到其他的window了。

    from selenium import webdriver
    
    from time import sleep
    
    from selenium.webdriver.common.alert import Alert
    
    driver = webdriver.Firefox()
    
    driver.maximize_window()
    
    driver.get('http://sahitest.com/demo/index.htm')
    
    current_window = driver.current_window_handle  # 获取当前窗口handle name
    
    driver.find_element_by_link_text('Window Open Test With Title').click()
    
    all_windows = driver.window_handles  # 获取所有窗口handle name
    
    # 切换window,如果window不是当前window,则切换到该window
    
    for window in all_windows:
    
        if window != current_window:
    
            driver.switch_to.window(window)
    
    print driver.title  # 打印该页面title
    
    driver.close()
    
    driver.switch_to.window(current_window)  # 关闭新窗口后切回原窗口,在这里不切回原窗口,是无法操作原窗口元素的,即使你关闭了新窗口
    
    print driver.title  # 打印原页面title
    
    driver.quit()

    div类对话框
    div类对话框是普通的网页元素,通过正常的find_element就可以定位并进行操作。不在这里进行详述。注意设置一定的等待时间,以免还未加载出来便进行下一步操作,造成NoSuchElementException报错。

     6、键盘操作

    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’)
    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包链接
      element_a = driver.find_element_by_xpath('//*[@id="content"]/section/div/div[2]/form/section[2]/ul/li[1]/a/h3/span[1]')#定位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,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。

    until

    method: 在等待期间,每隔一段时间(__init__中的poll_frequency)调用这个传入的方法,直到返回值不是False

    message: 如果超时,抛出TimeoutException,将message传入异常

    until_not

    与until相反,until是当某元素出现或什么条件成立则继续执行,

    until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。

    常用等待条件:

      • title_is :标题是某内容
      • title_contains :标题包含某内容
      • presence_of_element_located :节点加载出来,传入定位元组,如(By.ID, ‘p’)
      • presence_of_all_elements_located :所有节点加载出来
      • visibility_of_element_located :节点可见,传入定位元组
      • visibility_of :可见,传入节点对象
      • text_to_be_present_in_element :某个节点文本包含某文字
      • text_to_be_present_in_element_value :某个节点值包含某文字
      • invisibility_of_element_located :节点不可见
      • frame_to_be_available_and_switch_to_it :加载并切换
      • 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 :是否出现警告
    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)

    隐式等待:

    Selenium在DOM中没有找到节点,如果使用了隐式等待,Selenium将会进行等待,当超出设定时间后,则抛出找不到节点的异常。即当要查找的节点没有立即出现的时候,隐式等待将等待一段时间再查找DOM,默认的时间是0。调用driver的implicitly_wait()方法实现隐式等待:

    from selenium import webdriver
    
    driver = webdriver.Chrome()
    driver.implicitly_wait(10) #隐式等待设置等待时间为10s
    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时发生错误
    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)

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

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

    参考

    selenium webdrive使用

  • 相关阅读:
    Codeforces 1265A Beautiful String
    1039 Course List for Student (25)
    1038 Recover the Smallest Number (30)
    1037 Magic Coupon (25)
    1024 Palindromic Number (25)
    1051 Pop Sequence (25)
    1019 General Palindromic Number (20)
    1031 Hello World for U (20)
    1012 The Best Rank (25)
    1011 World Cup Betting (20)
  • 原文地址:https://www.cnblogs.com/code1992/p/13906281.html
Copyright © 2011-2022 走看看