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使用

  • 相关阅读:
    pandas 修改列顺序
    read_csv,to_csv 前n行
    郭盛华:未来黑客攻击的将远不止网络
    微软的 Linux 存储库停机 18 多个小时
    警惕黑客利用 Google Docs进行网络钓鱼
    苹果发布紧急补丁!修复被黑客利用的2个零日漏洞
    谷歌发布新框架以防止软件供应链攻击
    郭盛华:以知识见识锤炼真本领,年轻人要有理想
    通过 GDPR 加强密码政策,是企业网络的第一道防线
    肉类供应商遭黑客攻击,并支付了 1100 万美元的赎金
  • 原文地址:https://www.cnblogs.com/code1992/p/13906281.html
Copyright © 2011-2022 走看看