首页 > 其他分享 >13--selenium回顾

13--selenium回顾

时间:2024-01-19 23:34:17浏览次数:38  
标签:el 13 webdriver -- selenium driver element find

一 前期准备

1.1 概述

selenium本身是一个自动化测试工具。它可以让python代码调用浏览器,并获取到浏览器中加载的各种资源。

我们可以利用selenium提供的各项功能, 帮助我们完成数据的抓取

1.2 学习目标

  1. 掌握 selenium发送请求,加载网页的方法
  2. 掌握 selenium简单的元素定位的方法
  3. 掌握 selenium的基础属性和方法
  4. 掌握 selenium退出的方法

1.3 安装

安装:pip install selenium

它与其他库不同的地方是 它要启动你电脑上的浏览器, 这就需要一个驱动程序来辅助

推荐用chrome浏览器

chrome驱动地址:http://chromedriver.storage.googleapis.com/index.html

根据电脑的不同自行选择吧. win64、win32即可

把下载的浏览器驱动,放在python解释器所在的文件夹

Windwos: where Python 查看Python路径

Mac: open + 路径

例如:open /usr/local/bin/

前期准备工作完毕. 上代码看看 感受一下selenium

from selenium.webdriver import Chrome  # 导入谷歌浏览器的类


# 创建浏览器对象
web = Chrome()  # 如果你的浏览器驱动,放在了解释器文件夹

web.get("http://www.baidu.com")  # 输入网址
print(web.title)  # 打印title

运行一下你会发现神奇的事情发生了. 浏览器自动打开了. 并且输入了网址. 也能拿到网页上的title标题.

二 基本使用

2.1 加载网页

selenium通过控制浏览器,所以对应的获取的数据都是elements中的内容

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
# 访问百度
driver.get("http://www.baidu.com/")
# 截图
driver.save_screenshot("baidu.png")

2.2 定位和操作

# 搜索关键字 杜卡迪
driver.find_element(By.ID, "kw").send_keys("杜卡迪")


# 点击id为su的搜索按钮
driver.find_element(By.ID, "su").click()

2.3 查看请求信息

driver.page_source   # 获取页面内容
driver.get_cookies()
driver.current_url

2.4 退出

driver.close()  # 退出当前页面

driver.quit()   # 退出浏览器

2.5 小结

  1. selenium的导包:from selenium import webdriver
  2. selenium创建driver对象:webdriver.Chrome()
  3. selenium请求数据:driver.get("http://www.baidu.com/")
  4. selenium查看数据: driver.page_source
  5. 关闭浏览器: driver.quit()
  6. 根据id定位元素: driver.find_element_by_id("kw") / driver.find_element(By.ID, "kw")
  7. 操作点击事件: click()
  8. 给输入框赋值:send_keys()

三 元素定位及操作

学习目标

  1. 掌握 selenium定位元素的方法
  2. 掌握 selenium从元素中获取文本和属性的方法

3.1 元素定位

  1. 元素定位的两种写法:

    • 直接调用型

       el = driver.find_element_by_xxx(value)
       # xxx是定位方式,value为该方式对应的值
      
    • 使用By类型(需要导入By) 建议使用这种方式

       # 直接掉用的方式,会在底层翻译成这种方式
      from selenium.webdriver.common.by import By
      
      driver.find_element(By.xxx, value)
      
  2. 元素定位的两种方式:

    • 精确定位一个元素,返回结果为一个element对象,定位不到则报错

      driver.find_element(By.xx, value)  # 建议使用
      
      driver.find_element_by_xxx(value)
      
    • 定位一组元素,返回结果为element对象列表,定位不到返回空列表

      driver.find_elements(By.xx, value)  # 建议使用
      
      driver.find_elements_by_xxx(value)
      
  3. 元素定位的八种选择器:

    • By.ID 使用id值定位

      el = driver.find_element(By.ID, '')
      el = driver.find_element_by_id()            
      
    • By.XPATH 使用xpath定位

      el = driver.find_element(By.XPATH, '')
      el = driver.find_element_by_xpath()         
      
    • By.TAG_NAME 使用标签名定位

      el = driver.find_element(By.TAG_NAME, '')
      el = driver.find_element_by_tag_name()     
      
    • By.LINK_TEXT 使用超链接文本定位

      el = driver.find_element(By.LINK_TEXT, '')   # eg: a标签内容
      
      el = driver.find_element_by_link_text() 
      
    • By.PARTIAL_LINK_TEXT 使用部分超链接文本定位

      el = driver.find_element(By.PARTIAL_LINK_TEXT  , '')  #  eg: a标签内容 模糊匹配
      el = driver.find_element_by_partial_link_text()
      
    • By.NAME 使用name属性值定位

      el = driver.find_element(By.NAME, '')
      el = driver.find_element_by_name()
      
    • By.CLASS_NAME 使用class属性值定位

      el = driver.find_element(By.CLASS_NAME, '')   
      el = driver.find_element_by_class_name()
      
    • By.CSS_SELECTOR 使用css选择器定位

      el = driver.find_element(By.CSS_SELECTOR, '')  
      el = driver.find_element_by_css_selector()
      

注意:

  • by_link_textby_partial_link_text的区别:
    全部文本和包含某个文本
  • 使用: 以豆瓣为例

    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    driver = webdriver.Chrome()
    driver.implicitly_wait(10)  # 等待节点加载完成
    driver.get("https://www.douban.com/search?q=%E6%9D%B0%E6%A3%AE%E6%96%AF%E5%9D%A6%E6%A3%AE")
    time.sleep(2)
    # 使用id的方式获取右上角的搜索框
    # ret1 = driver.find_element(By.ID, 'inp-query')
    # ret1 = driver.find_element(By.ID, 'inp-query').send_keys("杰森斯坦森")
    # ret1 = driver.find_element_by_id("inp-query")
    # print(ret1)
    
    # 输出为:<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>
    
    # 搜索输入框  使用find_elements进行获取
    # ret2 = driver.find_elements(By.ID, "inp-query")
    # ret2 = driver.find_elements_by_id("inp-query")
    # print(ret2)
    #输出为:[<selenium.webdriver.remote.webelement.WebElement (session="ea6f94544ac3a56585b2638d352e97f3", element="0.5335773935305805-1")>]
    
    # 搜索按钮  使用xpath进行获取
    # ret3 = driver.find_elements(By.XPATH, '//*[@id="inp-query"]')
    # ret3 = driver.find_elements_by_xpath("//*[@id="inp-query"]")
    # print(len(ret3))
    # print(ret3)
    
    # 匹配图片标签
    ret4 = driver.find_elements(By.TAG_NAME, 'img')
    # ret4 = driver.find_elements_by_tag_name("img")
    for url in ret4:
        print(url.get_attribute('src'))
    
    print(len(ret4))
    
    ret5 = driver.find_elements(By.LINK_TEXT, "浏览发现")
    # ret5 = driver.find_elements_by_link_text("浏览发现")
    print(len(ret5))
    print(ret5)
    
    ret6 = driver.find_elements(By.PARTIAL_LINK_TEXT, "浏览发现")
    # ret6 = driver.find_elements_by_partial_link_text("浏览发现")
    print(len(ret6))
    
    # 使用class名称查找
    ret7 = driver.find_elements(By.CLASS_NAME, 'nbg')
    print(ret7)
    driver.close()                          
    

3.2 元素操作

find_element_by_xxx方法仅仅能够获取元素对象,接下来就可以对元素执行操作,从定位到的元素中提取数据的方法

1.从定位到的元素中,获取数据内容

el.id        # selenium提供的id,忽略

el.text      # 获取文本内容    开闭标签之间的文本内容
el.tag_name  # 获取标签名
el.location  # 获取位置 (x, y)
el.size      # 获取大小 (height, width)

    # 后续根据位置和大小把图截出来,一般是验证码,破解,自动输入
    图片四个点: 
    x, y           x+widht, y
    x, y+height    x+widht, y+height

    
# 3.获取属性
el.get_attribute('src')  

2.对定位到的元素,进行操作

el.click()           # 对元素执行点击操作

el.submit()          # 对元素执行提交操作

el.clear()           # 清空可输入元素中的数据

el.send_keys(data)   # 向可输入元素输入数据

使用示例:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver =webdriver.Chrome()

driver.get("https://www.douban.com/")
# 打印页面内容 (获取到以后可以进行后续的xpath,bs4 或者存储等)
print(driver.page_source)

ret4 = driver.find_elements(By.TAG_NAME, "h1")
print(ret4[0].text)
# 输出:豆瓣

ret5 = driver.find_elements(By.LINK_TEXT, "下载豆瓣 App")
print(ret5[0].get_attribute("href"))
# 输出:https://www.douban.com/doubanapp/app?channel=nimingye

driver.close()

四 其他操作

学习目标

  1. 掌握 selenium处理cookie等方法
  2. 掌握 selenium中switch的使用
  3. 掌握selenium中无头浏览器的设置

4.1 无头浏览器

无界面浏览器:不打开网页,让浏览器在后台跑

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options

opt = Options()
opt.add_argument("--headless")   # 浏览器不提供可视化页面
opt.add_argument('--disable-gpu') # 禁用gpu渲染  谷歌文档提到需要加上这个属性来规避bug
opt.add_argument("--window-size=4000,1600")  # 设置窗口大小

web = Chrome(options=opt)

4.2 cookies操作

# cookiesc操作
from selenium import webdriver

browser=webdriver.Chrome()
browser.get('https://www.zhihu.com/explore')

# 获取所有的cookies
print(browser.get_cookies())

# 设置cookies
browser.add_cookie({'k1':'xxx','k2':'yyy'})
print(browser.get_cookies())

# 删除一条cookie
browser.delete_cookie("CookieName")
# 删除所有的cookies
browser.delete_all_cookies()

4.3 页面等待

  • 为什么需要等待
    如果网站采用了动态html技术,那么页面上的部分元素出现时间便不能确定

    这个时候就可以设置一个等待时间,强制等待指定时间,等待结束之后进行元素定位,如果还是无法定位到则报错

  • 页面等待的三种方法

    • 强制等待

      import time
      time.sleep(n)     # 阻塞等待设定的秒数之后,再继续往下执行
      
    • 显式等待(自动化web测试使用,爬虫基本不用)

      from selenium.webdriver.common.keys import Keys
      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.baidu.com')
      
      WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.ID, "myDynamicElement"))
      # 显式等待指定某个条件,然后设置最长等待时间10,
      # 在10秒内每隔0.5秒使用指定条件去定位元素,如果定位到元素则直接结束等待,如果在10秒结束之后仍未定位到元素则报错
                                                            
      element = driver.find_element(By.CSS_SELECTOR,'#content_left')
      
    • 隐式等待 隐式等待设置之后,代码中的所有元素定位都会做隐式等待

      driver.implicitly_wait(10)    # 在指定的n秒内,每隔一段时间尝试定位元素,如果n秒结束还未被定位出来则报错
      
  • Selenium显示等待和隐式等待的区别
    1.selenium的显示等待
    原理:显示等待,就是明确要等到某个元素的出现或者是某个元素的可点击等条件

    ​ 等不到,就一直等,除非在规定的时间之内都没找到,就会跳出异常Exception

    ​ (简而言之,就是直到元素出现才去操作,如果超时则报异常)

    2.selenium的隐式等待

    原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间

    ​ 是得不到某个元素,就等待一段时间,直到拿到某个元素位置

    注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内部,不断的刷新页面,去寻找我们需要的元素

4.4 切换标签页

一个浏览器肯定会有很多标签页窗口,实现窗口的切换

使用 window_handles 方法来获取每个窗口的操作对象

# 1. 获取当前所有的标签页窗口
current_windows = driver.window_handles

# 2. 根据标签页窗口索引进行切换
driver.switch_to.window(current_windows[1])  # 调到下一个标签页窗口

driver.switch_to.window(web.window_handles[-1])  # 跳转到最后一个窗口

driver.switch_to.window(current_windows[0])  # 回到第一个窗口

4.5 切换frame框架页面

iframe是html中常用的一种技术,即一个页面中嵌套了另一个网页,selenium默认是访问不了frame中的内容的,对应的解决思路是

# 切换到某个 子frame
driver.switch_to.frame(name | el | id)  # 传入的参数 为iframe对应的id值 或 用元素定位之后的元素对象

# 切回父frame
driver.switch_to.parent_frame()

# eg:qq邮箱
在使用selenium登录qq邮箱的过程中,发现无法在邮箱的登录input标签中输入内容
通过观察源码可以发现,form表单在一个frame中,所以需要切换到frame中

4.6 处理页面弹窗

当你触发了某个事件之后,页面出现了弹窗提示,处理这个提示 或者 获取提示信息

alert = driver.switch_to_alert()

4.7 页面前进和后退

driver.forward()     # 前进
driver.back()        # 后退

driver.refresh()     # 刷新
driver.close()       # 关闭当前窗口

4.8 设置浏览器最大窗口

driver.maximize_window()  # 最大化浏览器窗口  全屏

# 具体大小
driver.set_window_size(width, height)

五 优缺点

  • 优点
    • selenium能够执行页面上的js,对于js渲染的数据和模拟登陆处理起来非常容易
    • 使用难度简单
    • 爬取速度慢,爬取频率更像人的行为,天生能够应对一些反爬措施
  • 缺点
    • 由于selenium操作浏览器,因此会将发送所有的请求,因此占用网络带宽
    • 由于操作浏览器,因此占用的内存非常大(相比较之前的爬虫)
    • 速度慢,对于效率要求高的话不建议使用

六 其他配置

https://blog.csdn.net/qq_35999017/article/details/123922952

https://blog.csdn.net/qq_27109535/article/details/125468643

标签:el,13,webdriver,--,selenium,driver,element,find
From: https://www.cnblogs.com/Edmondhui/p/17975840

相关文章

  • 图论练习笔记
    P1606[USACO07FEB]LilypadPondG首先跳的过程肯定不会经过相同位置,所以之前经过的位置可以视为原状态,所以可以把添加的莲花数量视为当前路径长度,问题也就转化成了最短路计数。因为求的是添加莲花的方案数而不是经过路径的方案数,所以可以把已有的莲花连通块缩起来,以水格子为状......
  • 高级架构师如何设计一个系统
    架构师如何设计系统?系统拆分通过DDD领域模型,对服务进行拆分,将一个系统拆分为多个子系统,做成SpringCloud的微服务。微服务设计时要尽可能做到少扇出,多扇入,根据服务器的承载,进行客户端负载均衡,通过对核心服务的上游服务进行限流和降级改造。一个服务的代码不要太多,1万行左右,两三......
  • hyperexpress框架/使用uwebsockets.js核心
    import{scheduleJob}from'node-schedule';//定时任务functionsetupScheduledTasks(){//每6秒执行一次setInterval(()=>{taskEverySixSeconds();},6000);//每33分钟执行一次setInterval(()=>{taskEve......
  • 【2015~2024】大牛直播SDK演化史
    大牛直播SDK的由来大牛直播SDK始于2015年,最初我们只是想做个低延迟的RTMP推拉流解决方案,用于移动单兵等毫秒级延迟的场景下,我们先是实现了Android平台RTMP直播推送模块,当我们用市面上可以找到的RTMP播放器测试时延的时候,居然都要6-7秒延迟,这在直播场景下,几乎是不可接受的,所以我们有......
  • 《Java实战(第2版)》PDF
    现代Java应用充分利用了微服务、反应式架构以及流式数据等创新设计。现代Java特性,譬如Lambda、流以及大家期待已久的Java模块系统让这些设计的实现极其便利。是时候更新技能工具箱了,只有这样,你才能从容应对迎面而来的种种挑战!本书通过透彻的示例和通俗的语言讲解了Java语言这些最激......
  • 《Java并发实现原理:JDK源码剖析》PDF
    《Java并发实现原理:JDK源码剖析》全面而系统地剖析了JavaConcurrent包中的每一个部分,对并发的实现原理进行了深刻的探讨。全书分为8章,第1章从最基础的多线程知识讲起,理清多线程中容易误解的知识点,探究背后的原理,包括内存重排序、happen-before、内存屏障等;第2~8章,从简单到复杂,逐......
  • java面向对象基础语法之两个对象的内存图
    一:概述在相关文章前面说明了一下一个对象的内存图,在这里将继续说明两个对象的内存图。二:具体说明<1>实例代码Student类publicclassStudent{Stringname;intage;Stringaddress;publicvoidstudy(){......
  • SpringBoot引入SpEL,优雅控制复杂权限!
    对于在Springboot中,利用自定义注解+切面来实现接口权限的控制这个大家应该都很熟悉,整体来说思路如下:自定义一个权限校验的注解,包含参数value配置在对应的接口上定义一个切面类,指定切点在切入的方法体里写上权限判断的逻辑然而,在实际的开发中,对于权限校验的需求场景是很多的,比如:傻眼......
  • 无涯教程-MATLAB - 变量声明
    在MATLAB环境中,每个变量都是一个数组或矩阵。您可以通过简单的方式分配变量。例如,x=3 %定义x并用一个值初始化它MATLAB将执行上述语句并返回以下输出-x=3它创建一个名为x的1-by-1矩阵,并将值3存储在其元素中,让我们再看一个例子,x=sqrt(16) %定义x并用表达式......
  • HarmonyOS NEXT开放:群星汇聚,开启万亿新蓝海
    从2019年HarmonyOS1.0落地,这四年多以来鸿蒙生态不断积蓄各方势能。伴随越来越多的开发者开始拥抱鸿蒙,鸿蒙已经成为一种社会现象。2024开年,鸿蒙再次成为焦点。1月18日,华为宣布HarmonyOSNEXT鸿蒙星河版开发者预览面向开发者开放申请,这意味着鸿蒙生态进入第二阶段,将加速千行百业的应......