python的webdriver应用

news2024/12/24 2:18:58

本文总结如何使用python的webdriver插件,应用自动化测试以及爬虫抓取数据。

工具选择

  1. 谷歌版本下载:https://www.iplaysoft.com/tools/chrome/

  1. webdriver版本:http://npm.taobao.org/mirrors/chromedriver/

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

webdriver和谷歌的版本需要对应,比如谷歌的版本是109,就得下载109版本的webdriver

  1. vscode开发工具:https://code.visualstudio.com/

  1. python3.7:https://www.python.org/downloads/

vscode的python插件

1、首先安装python3.7软件

window的cmd下,输入python若出现以下的提示,就是安装完成。

2、安装python插件

点击左侧栏Extension (或输入 Ctrl + shift + X) 进入插件面板。

3、创建venv虚拟目录

该目录下的文件,独立存放python的第三方软件包。比如在D盘新建一个文件夹venv,在vscode终端中运行以下命令。

D:                      #进入D盘
md venv                 #新建venv文件夹
python -m venv /venv    #使用Python创建venv环境
cd /venv
source bin/activate     #激活venv环境,可以看到虚拟环境中的 Package 只有最基础的 pip、setuptools
cd /venv
deactivate              #退出venv环境

使用pyvenv.cfg简化venv的开关,这样,vscode在运行相关Python程序的时候,就能自动开关venv环境了。

打开vscode,使用快捷键ctrl+shift+' 或 菜单栏-terminal-new terminal,打开终端

D:
cd /venv
source bin/activate
deactivate

通常,vscode就会在该目录下,自动创建一个pyvenv.cfg文件。

今后只要用vscode打开这个目录,直接运行Python程序,就会自动切换到venv模式下运行。

到这里就可以使用python自带pip工具,安装一个第三方软件selenium

pip3 install selenium

第一支脚本

webdriver是selenium的组件,Selenium 是一个 Web 的自动化测试工具,最初是为网站自动化测试而开发的。Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用。它支持所有主流的浏览器(包括 IE、Firefox、Safari、Opera 和 Chrome 等)。

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

class testlogin:
    def __init__(self):
        self.driver = webdriver.Chrome()
        self.driver.get("www.baidu.com")
if __name__ == "__main__":
    test=testlogin()

当然啦,也可以使用无界面形态。Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。相比于现代浏览器,Headless Chrome 更加方便测试 web 应用,获得网站的截图,做爬虫抓取信息等。相比于较早的 PhantomJS 等,Headless Chrome 则更加贴近浏览器环境

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

class testlogin:
    def __init__(self):
        #=====改写部分====begin
        chrome_options = webdriver.ChromeOptions()
        # 增加无界面选项
        chrome_options.add_argument('--headless')
        # 如果不加这个选项,有时定位会出现问题
        chrome_options.add_argument('--disable-gpu')
        #=====改写部分====end
        self.driver = webdriver.Chrome(options=chrome_options)
        self.driver.get("www.baidu.com")
if __name__ == "__main__":
    test=testlogin()

初识selenium

Selenium 提供了以下几种定位元素的方法:

描述

查找一个元素

查找多个元素

通过 ID 定位元素

find_element_by_id()

find_elements_by_id()

通过 Name 定位元素

find_element_by_name()

find_elements_by_name()

通过 XPath 定位元素

find_element_by_xpath()

find_elements_by_xpath()

通过完整链接文本定位超链接

find_element_by_link_text()

find_elements_by_link_text()

通过部分链接文本定位超链接

find_element_by_partial_link_text()

find_elements_by_partial_link_text()

通过标签名定位元素

find_element_by_tag_name()

find_elements_by_tag_name()

通过类名定位元素

find_element_by_class_name()

find_elements_by_class_name()

通过CSS选择器定位元素

find_element_by_css_selector()

find_elements_by_css_selector()

也可以用find_element统一函数写法,再在参数里声明通过什么方式定位元素,比如

find_element(By.ID,'元素ID') 对应 find_element_by_id('元素ID')

如何找到元素

比如登录百度账号,点击登录按钮,在浏览器上按下F12,按下图依次点击。

最后找到id=s-top-loginbtn,就是需要找的id元素,于是脚本就可以做以下的修改。

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By

class testlogin:
    def __init__(self):
        chrome_options = webdriver.ChromeOptions()
        # 增加无界面选项
        chrome_options.add_argument('--headless')
        # 如果不加这个选项,有时定位会出现问题
        chrome_options.add_argument('--disable-gpu')
        self.driver = webdriver.Chrome(options=chrome_options)
        self.driver.get("www.baidu.com")
    #=====新增部分====begin
    def loginClick(self):
        loginbtn = self.driver.find_element(By.ID,'s-top-loginbtn')        
        loginbtn.click()        
    #=====新增部分====end

if __name__ == "__main__":
    test=testlogin()
    test.loginClick()

一些高阶写法

1、如何跳转页面

需要准确跳转至页面,才能取到元素。

第一种情况:同一页面里有多个frame的话,就得找到对应的frame才行。

#    转到页面
    def switchIframe(self,src):
        #返回到主窗体
        self.driver.switch_to.default_content()
        iframes = self.driver.find_elements(By.TAG_NAME,"iframe")
        iframe = None
        for frm in iframes:
            if re.search(src,frm.get_attribute("src"))!=None:
                iframe=frm     
        self.driver.switch_to.frame(iframe)

第二种情况,同时找开了多个页面

    def switchWindow(self,url):
        windows = self.driver.window_handles
        for w in windows:
            self.driver.switch_to.window(w)
            if self.driver.current_url.startswith(url):
#                print(self.driver.title)
                break
        #有时只需要找开最后一个页面。
        self.driver.switch_to.window(self.driver.window_handles[-1])
        self.driver.maximize_window()

2、xpath写法详解

其实xpath用法比较复杂,一般只会用到第1,2,3点。第4,5,6点需要的时候再查找的。

2.1基本用法:

//tagname[@attribute=‘value’]

其中,tagname表示标签名称,@后面跟随属性名称,等号后面是属性值。如果需要查找多重下级,则在父级的xpath路径后继续追加定位,例如://div[@id='car_genre_id']/div/div,表示 id是car_genre_id的div元素的子节点div的子节点div。

2.2xpath的绝对路径和相对路径

1)单斜线‘/’代表绝对路径,表示该符号后面的元素是上一级节点的子节点的一个,只能一级级按序向下查询,不能跳级;

2)双斜线'//'代表相对路径,表示下级任何子节点或者任何嵌套子节点中的一个,可以跳级;

  举个栗子,在路径//div[@id='root']/input中,表示越过所有父节点,直接在整个html页面中查找id是'root'的div元素,因为div标签前是代表相对定位的双斜线'//';而对于input标签来说,它必须是id是'root'的div的一级子节点,它和div中间不能越过其他的层级,因为input标签前是代表绝对路径的单斜线'/' 。

2.3如何获取元素的xpath路径

  大多浏览器的开发者模式中都具备了输出元素xpath路径的功能。以chrome为例,点击F12后,在DOM树中选中元素,右键> Copy > CopyXpath后,在记事本上黏贴,即可得到该元素的xpath路径。

2.4使用contains属性查找元素

    contains表示查找属性包含该属性值value的页面标签元素,注意是包含,并不是完全等于,类似于sql查找语句中like的用法。

    语法为: //tagname[contains(attribute1,'value1') and contains(attribute2,'value2') and ... ]

    举个例子,路径 //div[@id="root"]//div[contains(text(),'共'] ,表示在id是'root'的div中,越过层级关系,查找文本信息包含"共"的div元素;

    路径//div[@id='root']//div[contains(className,'ant-Btn')], 表示在id是'root'的div中,越过层级关系,查找className属性中包含'ant-Btn'属性的元素;

2.5 查找父级节点和平级节点

2.5.1父节点定位子节点:

# 1.串联寻找
print driver.find_element_by_id('B').find_element_by_tag_name('div').text
# 2.xpath父子关系寻找
print driver.find_element_by_xpath("//div[@id='B']/div").text
# 3.css selector父子关系寻找
print driver.find_element_by_css_selector('div#B>div').text
# 4.css selector nth-child
print driver.find_element_by_css_selector('div#B div:nth-child(1)').text
# 5.css selector nth-of-type
print driver.find_element_by_css_selector('div#B div:nth-of-type(1)').text
# 6.xpath轴 child
print driver.find_element_by_xpath("//div[@id='B']/child::div").text driver.quit()

2.5.2由子节点定位父节点:

这里我们有两种办法,第1种是 .. 的形式,就像我们知道的,. 表示当前节点,.. 表示父节点;第2种办法跟上面一样,是xpath轴中的一个:parent,取当前节点的父节点。这里也是css selector的一个痛点,因为css的设计不允许有能够获取父节点的办法(至少目前没有)

# 1.xpath: `.`代表当前节点; '..'代表父节点
print driver.find_element_by_xpath("//div[@id='C']/../..").text
# 2.xpath轴 parent
print driver.find_element_by_xpath("//div[@id='C']/parent::*/parent::div").text

2.5.3由弟弟节点定位哥哥节点

# 1.xpath,通过父节点获取其哥哥节点
print driver.find_element_by_xpath("//div[@id='D']/../div[1]").text
# 2.xpath轴 preceding-sibling
print driver.find_element_by_xpath("//div[@id='D']/preceding-sibling::div[1]").text

2.5.4由哥哥节点定位弟弟节点

# 1.xpath,通过父节点获取其弟弟节点
print driver.find_element_by_xpath("//div[@id='D']/../div[3]").text
# 2.xpath轴 following-sibling
print driver.find_element_by_xpath("//div[@id='D']/following-sibling::div[1]").text
# 3.xpath轴 following
print driver.find_element_by_xpath("//div[@id='D']/following::*").text
# 4.css selector +
print driver.find_element_by_css_selector('div#D + div').text
# 5.css selector ~
print driver.find_element_by_css_selector('div#D ~ div').text

2.6使用xpath定位元素时需要注意的地方

  1)保证xpath路径的唯一性。

    一定要保证xpath路径在页面中是唯一的。如果不太确定,可以在chrome的开发者工具打开的情况下,点击ctrol+F,在弹出的输入框中输入xpath

的路径,观察当前页面下,以该路径查找到的元素是不是只有一个;

  2)尽量不要使用通配符*

    *表示可以是当前页面中的任意标签,这样在查找时会增大负载,尽量准确地写出标签名称

  3)建议使用相对路径定位

    如果前面页面的元素结构发生调整,那么之前的绝对定位就会作废。而使用相对路径,可以减少定位对页面HTML元素结构的依赖性,且相对路径

往往长度较短,更加准确美观。在优化定位方式时,可以将此原则作为参考。

3、执行js脚本

有时直接用selenium接口操作元素失效,不妨尝试直接执行js脚本。

    def executeJs(self):
        jsStr = "document.getElementById('append').getElementsByTagName('li')[0].click()"
        self.driver.execute_script(jsStr)

4、等待元素出现再操作

有时某个元素需等待一段时间才会出现,如果用time.sleep(20000),等待20秒,再执行点击操作,也可以,只是有点low;有时网络没有延迟或页面响应较快,不用等20秒,而是等1秒就出现呢,为了保证元素出现,程序每次都会等待20秒,这样等待时长也是挺难受的。

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
#    设置等待20秒超时时间,20秒内,如果出现id='append',就直接执行点击操作
def waitForShow(self):
        append = WebDriverWait(self.driver, 20).until(expected_conditions.presence_of_element_located((By.ID, "append")))
        append.click()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164350.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

顺序表学习指南,请查收~

作者:爱塔居的博客_CSDN博客-JavaSE,数据结构领域博主 专栏:数据结构 作者简介:大三学生,希望一起进步! 文章目录 目录 文章目录 一、顺序表基本概念 二、练习 一、顺序表基本概念 🌺顺序表是用一段物理地…

常用工具的常用操作

写在前面 记录可能用到的各种工具常见技巧。 1:sublime 1.1:操作多列 首先选中要操作的列所在的行: 然后点击selection,spit lines: 接下来移动左右键就可以操作了,删除或者批量添加内容: 1…

创客匠人助力机构招生获客转化

后疫情时代,各行各业部署线上化成为一门必修课。 创客匠人作为一家专注教育培训行业的知识付费技术服务商,为了更好的帮助教培机构、教育企业立足于内容传播需求,打通线上线下资源通道,将线下资源向"线上核心平台"靠拢…

无极低码:100套大屏可视化源码,包含多个行业

随着互联网的发展,各项技术的不断成熟,数据可视化在新的时代,人们对数据的呈现方式开始有了新的要求。科技感、美观、直观、动感等等都成为现代软件系统新的设计和思考方向,特别是硬件的发展和数据的发展,数据分析的需…

Vue3商店后台管理系统设计文稿篇(一)

记录使用vscode构建Vue3商店后台管理系统,这是第一篇,主要记录Vue3项目创建过程,以及数据的挂载 文章目录一、Vue3项目创建二、取消代码规范检查三、数据简单挂载正文内容: 一、Vue3项目创建 使用如下命令全局安装yarn npm i -g …

Java开发 - Mybatis框架初体验

前言 在前文中,我们已经学习了Spring框架,Spring MVC框架,相信大家对这些基础的内容已经熟练使用了,今天,我们继续来学习Mybatis框架。就目前而言,Mybatis框架依然是比较实用的框架,这篇博客&a…

SpringMVC知识点记录

SpringMVC知识点记录1. SpringMVC简介2. 入门案例3. RequestMapping注解4. SpringMVC获取请求参数5. 域对象共享数据6.SpringMVC的视图7. RESTful8. RESTful 案例9. SpringMVC处理ajax请求10. 文件上传和下载11. 拦截器12. 异常处理器13. 注解配置SpringMVC14. SpringMVC执行流…

hgame2023 week1 writeup

#WEEK1 RE 1、re-test_your_IDA ida打开可见flag: int __cdecl main(int argc, const char **argv, const char **envp) {char Str1[24]; // [rsp20h] [rbp-18h] BYREFsub_140001064("%10s");if ( !strcmp(Str1, "r3ver5e") )sub_140001010…

移动端 - 搜索组件(search-input篇)

我们先来看一下最终效果 这样的搜索组件在移动端是很常见的, 大部分需求都是: 1. 搜索框进行搜索关键字 2. 热门搜索 3. 搜索历史 4. 搜索结果(提供上拉加载效果) 上述的基本需求也是我们现在需要去实现的, 先来说一下大致的方向: 1. search 一般都是一个路由组件, 所以先…

20.Isaac教程--Python接口(Python API)

Isaac Python接口(Python API) ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 虽然 Isaac SDK 的大部分部分都是用 C 编码的,但您可以选择使用 Python 构建您的应用程序。 本文档介绍了 Isaac SDK 的 Python API。 Python API 允许您…

Day859.高性能队列Disruptor -Java 并发编程实战

高性能队列Disruptor Hi,我是阿昌,今天学习记录的是关于高性能队列Disruptor的内容。 并发容器 中Java SDK 提供了 2 个有界队列: ArrayBlockingQueueLinkedBlockingQueue 它们都是基于 ReentrantLock 实现的,在高并发场景下&…

人工智能的过去与未来——萌芽

1943年—M-P模型 美国神经生理学家Warren McCulloch和数理逻辑学家Walter Pitts在合作的《A logical calculus of the ideas immanent in nervous activity》论文中对生物神经元进行建模,并提出了一种形式神经元模型,命名为McCulloch-Pitts模型。 生物…

65. Python __init__方法

65. __init__方法 文章目录65. __init__方法1. 知识回顾在类的方法中调用类的属性2. 知识回顾调用方法时传值3.体验__init__方法4. __init__的作用5. __init__方法的写法6. __init__方法调用类的属性7. 课堂实操1. 知识回顾在类的方法中调用类的属性 【目标任务】 创建一个类…

C++程序设计——类的六个成员函数

类的六个成员函数 空类中真的什么都没有吗? 事实上任何一个类,在我们不写的情况下,都会自动生成6个默认的成员函数。 1.构造函数 概念: 构造函数是一个特殊的成员函数,名字与类名相同,实例化对象时由编译器…

【基于机械臂触觉伺服的物体操控研究】几种轨迹规划的算法及代码实现

我的毕设题目定为《基于机械臂触觉伺服的物体操控研究》,这个系列主要用于记录做毕设的过程。 轨迹规划是机器人绕不过去的话题,其目的是为了让机器人的运动更加的平滑。对于四足机器人,贝赛尔曲线的应用比较普遍。而对于机械臂,…

【C++】C++ 入门(一)

目录 一、前言 1、什么是C 2、C关键字(C98) 二、第一个C程序 三、命名空间 1、存在意义 2、命名空间定义 3、命名空间的使用 3.1、指定命名空间访问 3.2、全局展开访问 3.3、部分展开访问 四、C输入&输出 五、缺省参数 1、缺省参数概念 2、缺省参数分类 2.…

【Day4】24两两交换链表中的节点、19删除链表的倒数第N个节点、链表相交、142环形链表Ⅱ

【Day4】24两两交换链表中的节点、19删除链表的倒数第N个节点、160链表相交、142环形链表Ⅱ24.两两交换链表的点19.删除链表的倒数第N个节点160链表相交 面试题02.07142 环形链表Ⅱ判断链表是否有环若链表有环,如何找到环的入口24.两两交换链表的点 题目链接&#…

Spacedesk 安装教程及连接后黑屏解放方法

spacedesk 安装教程1. Spacedesk 概述2. Spacedesk 安装教程2.1 下载 Spacedesk2.2 连接计算机的 Spacedesk3. 被拓展的设备连接后黑屏的解决方法结束语1. Spacedesk 概述 Spacedesk 是一款低延迟的免费显示器拓展软件,且不需要线材将不同设备连接; Spa…

MySQL中的普通索引和唯一索引实际开发中的选择

文章目录前言一、普通索引和唯一索引介绍二、查询语句的比较三、更新语句的比较四、索引的选择和实践前言 本文我们将会从针对普通索引与唯一索引的增删改查的具体执行流程,来看看效率的对比。以便让我们在实际业务开发中可以进行更好的选择。 一、普通索引和唯一索…

动态规划系列 —— 背包问题

什么是背包问题 背包问题是有N件物品,容量为V的背包 每个物品有两个属性:体积,价值,分别用数组v,w表示 第i件物品的体积为v[i],价值为w[i] 计算在背包装得下的情况下,能装的最大价值是多少&…