Selenium的使用

Selenium 是一个自动化测试工具,它主要用于自动化网络应用程序的测试。不过,除了测试之外,它也常用于自动执行各种浏览器操作,比如自动填写表单、抓取网页数据、点击、下拉等。同时还可以获取浏览器当前所呈现的页面的源代码,做到可见即可爬,对于一些JavaScript动态渲染的页面来说,非常有效

一 准备工作

谷歌浏览器为例,在开始之前确保已经安装好了浏览器并配置好了ChromeDriver,另外还需要安装python第三方selenium库。

1 安装库

pip install selenium

2 安装驱动

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

注意:

        驱动要对应浏览器版本,否则无法驱动

        禁止浏览器更新services.msc找到给禁止

安装细节:

查看浏览器版本:浏览器三个小点--设置--关于谷歌

找到类似的版本的驱动

找一个下载win版本的然后解压,安装

将驱动的.exe文件放在python的安装目录下(或者把路径给配置到环境变量中,可以通过cmd输入chromedriver运行)

禁止更新服务:

win+R   - services.msc找到下面的给禁止

如果版本超过114,进入下面的连接下载对应版本(下载win32)

Chrome for Testing availabilityicon-default.png?t=N7T8https://googlechromelabs.github.io/chrome-for-testing/

二 声明浏览对象

Selenium支持众多的浏览器,如Chrome、Firefox、Edge等,还有Android、BlackBerry等手机端的浏览器。另外,也支持无界面的浏览器PhantomJS

初始化方式如下:

from selenium import webdriverbrowser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.Safari()

三 基本使用

打开一个网站然后关闭,具体代码如下

from selenium import webdriver
import time
# 创建一个浏览器对象
browser = webdriver.Chrome()
# 打开指定网页
browser.get('https://www.baidu.com/')
# 停留5秒
time.sleep(5)
# 退出浏览器
browser.quit()

用浏览器搜索指定内容

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
# 提前添加配置信息
options = webdriver.ChromeOptions()
# 设置浏览器不被检测
options.add_argument('--disable-blink-features=AutomationControlled')
# 创建一个浏览器对象
browser = webdriver.Chrome()
# browser = webdriver.Chrome(options = options)
# 打开指定网页
browser.get('https://www.baidu.com/')
# 搜索中国武警
#     定位
browser.find_element(By.ID, 'kw').send_keys('中国武警')
# 点击搜索
browser.find_element(By.ID,'su').click()
# 停留5秒
time.sleep(5)
# 退出浏览器
browser.quit()

(可能会检测出来是非人为操作,通过提前配置浏览器参数解决)

设置屏蔽

options = webdriver.ChromeOptions()
# 设置浏览器不被检测
options.add_argument('--disable-blink-features=AutomationControlled')
# 创建一个浏览器对象
browser = webdriver.Chrome(options = options)

模拟键盘操作

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys #模拟键盘操作
import time
# 提前添加配置信息
options = webdriver.ChromeOptions()
# 设置浏览器不被检测
options.add_argument('--disable-blink-features=AutomationControlled')
# 创建一个浏览器对象
browser = webdriver.Chrome()
# 打开指定网页
browser.get('https://www.baidu.com/')
# 搜索中国武警
#     定位
s = browser.find_element(By.ID, 'kw')
s.send_keys('中国武警')
# 回车搜索
s.send_keys(Keys.ENTER)
time.sleep(10)

四 查找结点

        匹配单个节点

find_element()

# 通过 ID 定位元素
find_element(By.ID, "element_id")
# 通过类名定位元素
find_element(By.CLASS_NAME, "element_class")
# 通过名字定位元素
find_element(By.NAME, "element_name")
# 通过 CSS 选择器定位元素
find_element(By.CSS_SELECTOR, "css_selector")
# 通过 XPath 定位元素
find_element(By.XPATH, "xpath_expression")
# 通过链接文本定位超链接
find_element(By.LINK_TEXT, "link_text")
# 通过部分链接文本定位超链接
find_element(By.PARTIAL_LINK_TEXT, "partial_link_text")
# 通过标签名定位元素
find_element(By.TAG_NAME, "tag_name")

        多个节点

find_elements()

五 节点交互

Selenium可以驱动浏览器来执行一系列操作,即让浏览器执行一些动作。常见用法:输入文字时用send_keys方法,清空文字用clear方法,点击按钮用click方法。示例如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
browser = webdriver.Chrome()
browser.get('https://www.baidu.com/')
s = browser.find_element(By.ID, 'kw')
s.send_keys('李宁')
time.sleep(1)
s.clear()
s.send_keys('耐克')
but = browser.find_element(By.ID,'su')
but.click()
time.sleep(10)

六 动作链

上面例子中,一些交互动作都是针对某个节点执行的,如,对于输入框,用他的输入文字和清空文字方法;对于按钮,调用它的点击方法。另外一种操作,没有特定的执行对象,如鼠标拖拽,键盘按键等,这些动作通过另一种形式来执行,那就是动作链。

比如,现在实现一个节点的拖拽操作,将某个节点从一处拖拽到另一处,可以这样实现:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
browser = webdriver.Chrome()
url = 'https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable'
browser.get(url)
browser.switch_to.frame('iframeResult') #切换到嵌套的网页(frame的为iframeResult的网页)
source = browser.find_element(By.CSS_SELECTOR,'#draggable')
target = browser.find_element(By.CSS_SELECTOR,'#droppable')
action = ActionChains(browser)
action.drag_and_drop(source,target)
action.perform()

首先,打开一个网页的拖曳实例,然后依次选中要拖曳的节点和拖曳后的节点,接着声明ActionChains对象并赋值给action,然后通过调用drag_and_drop()方法,再调用perform()方法执行动作,此时就完成了拖曳操作。

        页面滚动

移动元素element元素的顶端与当前窗口的顶部对齐

execute_script(“argument[0].scrollIntoView();”,element)
execute_script(“argument[0].scrollIntoView(True);”,element)

移动元素element对象的底端与当前窗口的底部对齐

execute_script(“argument[0].scrollIntoView(False);”,element)

移动到页面最底部(scrollTo(x,y),x指的是x轴坐标,y指的是y轴坐标

execute_script("window.scrollTo(0,document.body.scrollHeight)")

移动到指定的坐标(相对当前的坐标)

execute_script("window.scrollBy(0,700)")

结合上面的scrollBy语句,相当于移动到700+800px位置

execute_script("window.scrollBy(0,800)")

移动到窗口绝对位置坐标

execute_script("window.scrollTo(0,700)")

七 执行JS

对于某些操作,Selenium API没有提供,比如,下拉进度条,它可以通过直接模拟运行JavaScript,此时使用execute_script()方法即可以实现,代码如下:

# document.body.scrollHeight   获取页面高度
# 按F12之后在控制台输入document.body.scrollHeight 可以查看页面高度
from selenium import webdriver
import time,random
browser = webdriver.Chrome()
browser.get('https://36kr.com/')
# # 下拉边框,一次性拉到位
# browser.execute_script('window.scrollTo(0,document.body.scrollHeight)')
# 慢慢下拉
for i in range(1,9):time.sleep(random.randint(100,300)/1000)browser.execute_script('window.scrollTo(0,{})'.format(i*1000))
time.sleep(10)

这里利用execute_script()方法将进度条拉到最底部

所以说有了这个方法,基本上API没有提供的所有功能都可以执行JavaScript方式来实现

八 获取节点信息

        获取属性

可以使用get_attribute()方法来获取节点的属性,但是其前提是先选中这个节点,示例如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
url = 'https://pic.netbian.com/4Kxinnian/'
browser = webdriver.Chrome()
browser.get(url)
src = browser.find_elements(By.XPATH,'//ul[@class="clearfix"]/li/a/img')
for i in src:
# 获取i中的src属性url = i.get_attribute('src')print(url)

通过get_attribute()方法,然后传入想要获得的属性名,就可以得到它的值了。

        获取ID、位置、标签名、大小

另外,WebElement节点还有一些其他属性,比如id属性可以获取节点id,location属性可以获取该节点在页面中的相对位置,tag_name 属性可以获取标签名称,size属性可以获取节点的大小(宽高),示例如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
# 安装Pillow库
from PIL import Image
from io import BytesIO
url = 'https://pic.netbian.com/4Kxinnian/'
browser = webdriver.Chrome()
browser.get(url)
img = browser.find_element(By.XPATH,'//ul[@class="clearfix"]/li[1]/a/img')
location = img.location
size = img.size
print(location,size)
# top bottom left right 分别代表上边界 下边界 左边界 右边界
top,bottom,left,right = location['y'],location['y']+size['height'],location['x'],location['x']+size['width']
print(top,bottom,left,right)
screen = browser.get_screenshot_as_png()
screen = Image.open(BytesIO(screen))
cap = screen.crop((top,left,right,bottom))
cap.save('1.png')

九 切换Frame

我们知道网页中有一种节点叫做iframe,也就是子Frame,相当于页面的子页面,它的结构和外部网页的结构完全一致。Selenium打开页面后,它默认是在父级Frame里面进行操作的,而此时页面中还有子Frame,它是不能获取到子Frame里面的节点的,这是需要使用switch_to.frame()方法来切换Frame。示例如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
browser.get('https://www.douban.com')
login_frame = browser.find_element(By.XPATH,'//div[@class="login"]/iframe')
browser.switch_to.frame(login_frame)
s = browser.find_element(By.CLASS_NAME,'account-tab-account')
s.click()
browser.find_element(By.ID,'username').send_keys('123456')

十 延时等待

在Selenium中,get()方法会在网页框架加载结束后结束执行,次数如果获取page_source,可能并不是浏览器完全加载完成的界面,如果某些页面有额外的Ajax请求,我们在页面源代码中也不一定能够获取到。所以,这里需要延时等待一定时间,确保节点已经加载出来,这里等待的方式有两种,显式等待和隐式等待。

        隐式等待

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

        显式等待

隐式等待效果并没有那么好,因为我们只规定了一个固定的时间,而页面加载受网络等条件的影响。

显示等待方法,它指定要查找的节点,然后指定一个最长的等待时间。如果在规定的时间内加载出来这个节点,就返回查找的节点,如果没有加载出来,则抛出超时异常,示例如下

十一 前进后退

平时使用浏览器都有前进和后退功能,Selenium也可以完成这样的操作,它使用back()方法后退,使用forward()方法前进,示例如下:

from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.get('https://www.douban.com')
browser.get('https://www.jd.com')
browser.back()
time.sleep(1)
browser.forward()
browser.close()

十二 Cookies

使用Selenium,还可以方便的对Cookies进行操作,获取、添加、删除Cookies等

from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('https://www.zhihu.com')
print(browser.get_cookies())
browser.add_cookie({'name':'name','domain':'www.zhihu.com','value':'germy'})
print(browser.get_cookies())
browser.delete_all_cookies()
print(browser.get_cookies())

十三 选项卡管理

在访问页面的时候,会开启一个个选项卡。在Selenium中,我们也可以对选项卡进行操作

from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
browser.execute_script('window.open()')
print(browser.window_handles)
browser.switch_to.window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(1)
browser.switch_to.window(browser.window_handles[0])
browser.get('https://www.jd.com')

首先访问百度,然后调用execute_script()方法执行window.open()这个JavaScript语句开启一个选项卡。接下来我们想切换到该选项卡。调用window_handles属性获取当前开启的所有选项卡,返回选项卡的代号序列。使用switch_to.window()方法切换选项卡,其中参数一是选项卡的代号,我们将第二个选项卡的代号传入,即跳转到第二个选项卡,然后在第二个选项卡上打开淘宝,然后再切换到第一个选项卡(重新调用switch_to.window()方法),打开京东。

十四 异常处理

在使用Selenium的过程中,难免会遇到一些异常,例如超时、节点未找到等错误,一旦出现此类错误,程序便不会执行。这里使用try expect语句来捕获各种异常。

from selenium import webdriver
from selenium.common.exceptions import TimeoutException,NoSuchElementException
from selenium.webdriver.common.by import By
browser = webdriver.Chrome()
try:browser.get('https://www.baidu.com')
except TimeoutException:print('超时!')
try:browser.find_element(By.ID,'hello')
except NoSuchElementException:print('没有此类节点')
finally:browser.close()

十五 绕过检测

无处理:

browser = get('https://www.baidu.com')

设置屏蔽

options = webdriver.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
browser = webdriver.Chrome(options = options)
browser.get('https://www.baidu.com')

十六 教学案例

采集义乌购商品网站

完整流程如下图所示:

代码实现:

from selenium import webdriver
from selenium.webdriver.common.by import By
import time,random
from selenium.common.exceptions import NoSuchElementException
import pymysqlclass YwShop():def __init__(self):# 初始化函数,提供配置项,设置屏蔽,防止网站检测出是爬虫options = webdriver.ChromeOptions()options.add_argument('--disable-blink-features=AutomationControlled')self.browser = webdriver.Chrome(options=options)def base(self):# 访问网站self.browser.get('https://www.yiwugo.com/')# 获取输入框input = self.browser.find_element(By.ID,'inputkey')# 发送参数input.send_keys('饰品')# 点击事件self.browser.find_element(By.XPATH,'//div[@class="search-index"]/span[last()]').click()print('调用访问网站函数')def spider(self):# 下拉翻页# window.document.documentElement.scrollHeight  在控制台输入查看网页高度self.drop_down()# 定位数据区域li = self.browser.find_elements(By.CLASS_NAME,'pro_list_product_img2')for i in li:# 定位数据title = i.find_element(By.XPATH,'.//li/a[@class="productloc"]')price = i.find_element(By.XPATH,'.//li/span[@class="pri-left"]/em')info = i.find_elements(By.XPATH,'.//li/span[@class="pri-right"]/span')address = i.find_element(By.XPATH,'.//li[@class="shshopname"]')texts = ''for j in info:texts=texts+j.text# 构造数据结构items = {'标题':title.text,'价格':price.text,'地址':address.text,'信息':texts}# 调用保存逻辑self.save_mysql(items)# 翻页self.page_next()def save_mysql(self,data):title = data.get('标题')price = data.get('价格')address = data.get('地址')texts = data.get('信息')db = pymysql.connect(host='localhost',user='root',password='123456',port=3306,db='test1')cursor = db.cursor()sql = 'insert into yiwudb(title,price,address,texts) values(%s,%s,%s,%s)'try:cursor.execute(sql,(title,price,address,texts))db.commit()except Exception as e :print('出错信息:',e)db.rollback()db.close()def page_next(self):# 定位翻页try:next = self.browser.find_element(By.XPATH,'//ul[@class="right"]/a[@class="page_next_yes"]')if next:next.click()self.spider()else:self.browser.close()except Exception as e:print(e)def drop_down(self):# 下拉页面for i in range(1,10):j = i/10js = f'window.scrollTo(0,document.body.scrollHeight * {j})'self.browser.execute_script(js)time.sleep(random.randint(400,800)/1000)if __name__ == '__main__':f = YwShop()f.base()f.spider()

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

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

相关文章

【VRTK】【Unity】【游戏开发】更多技巧

课程配套学习项目源码资源下载 https://download.csdn.net/download/weixin_41697242/88485426?spm=1001.2014.3001.5503 【概述】 本篇将较为零散但常用的VRTK开发技巧集合在一起,主要内容: 创建物理手震动反馈高亮互动对象【创建物理手】 非物理手状态下,你的手会直接…

Vue+ElementUI+Axios实现携带参数的文件上传(数据校验+进度条)

VueElementUIAxios实现携带参数的文件上传(数据校验进度条) 可以实现对上传文件的类型,大小进行数据校验,以及对上传文件所要携带的数据也进行的校验,也有文件上传进度的进度条。 一、Vue 结构部分 弹窗显示&#xff0…

【服务器数据恢复】服务器硬盘磁头损坏的数据恢复案例

服务器硬盘故障: 一台服务器上raid阵列上有两块硬盘出现故障,用户方已经将故障硬盘送到其他机构检测过,其中一块硬盘已经开盘,检测结果是盘片损伤严重;另一块硬盘尚未开盘,初步判断也存在硬件故障&#xff…

UCB Data100:数据科学的原理和技巧:第十三章到第十五章

十三、梯度下降 原文:Gradient Descent 译者:飞龙 协议:CC BY-NC-SA 4.0 学习成果 优化复杂模型 识别直接微积分或几何论证无法帮助解决损失函数的情况 应用梯度下降进行数值优化 到目前为止,我们已经非常熟悉选择模型和相应损…

机器学习-决策树

1、什么是决策树? 一种描述概念空间的有效的归纳推理办法。基于决策树的学习方法可以进行不相关的多概念学习,具有简单快捷的优势,已经在各个领域取得广泛应用。 决策树是一种树型结构,其中每个内部结点表示在一个属性上的测试&a…

Pandas十大练习题,掌握常用方法

文章目录 Pandas分析练习题1. 获取并了解数据2. 数据过滤与排序3. 数据分组4. Apply函数5. 合并数据6. 数据统计7. 数据可视化8. 创建数据框9. 时间序列10. 删除数据 代码均在Jupter Notebook上完成 Pandas分析练习题 数据集可从此获取: 链接: https://pan.baidu.co…

flutter动态渲染从服务器请求的列表数据

比如我们从服务器请求到的列表数据,需要渲染到页面上,但是在flutter里面还是需要使用他们的ListView或者GridView或者别的组件才可以,或者有children这种属性的组件上使用。 比如我们在一个有状态的组件Lists里面,在initState的时…

uniapp 实战 -- app 的自动升级更新(含生成 app 发布页)

uniapp 提供了 App升级中心 uni-upgrade-center ,可以便捷实现app 的自动升级更新,具体编码和配置如下: 1. 用户端 – 引入升级中心插件 下载安装插件 uni-upgrade-center - App https://ext.dcloud.net.cn/plugin?id4542 pages.json 中添加…

在机械行业中,直线导轨和弧形导轨哪个应用范围更广泛?

弧形导轨和直线导轨是两种常见的导轨类型,直线导轨主要被用于高精度或快速直线往复运动场所,而弧形导轨是一种专门设计用于曲线运动的导轨系统,那么在机械行业中,直线导轨和弧形导轨哪个应用范围更加广泛呢? 直线导轨主…

蚂蚁爱购--靠谱的SpringBoot项目

简介 这是一个靠谱的SpringBoot项目实战,名字叫蚂蚁爱购。从零开发项目,视频加文档,十天就能学会开发JavaWeb项目。 教程路线是:搭建环境> 安装软件> 创建项目> 添加依赖和配置> 通过表生成代码> 编写Java代码&g…

如何关闭iPhone 14或14 Pro Max,这里有详细步骤

你刚买了新的iphone 14或iphone 14 pro max,迫不及待地想开始使用它。但如果你需要关闭它怎么办?有几种方法可以用来关闭这两种设备。 如何关闭iPhone 14 你可以通过每个人都熟悉的老式侧按钮轻松关闭iPhone 14,也可以通过面部识别关闭它。 …

Springboot+vue的智能无人仓库管理(有报告),Javaee项目,springboot vue前后端分离项目

演示视频: Springbootvue的智能无人仓库管理(有报告),Javaee项目,springboot vue前后端分离项目 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的智能无人仓库管理,采用M&#xff08…

Linux/Frolic

Enumeration nmap 还是扫描系统对外开放的端口情况,对外开放了22,139,445,还有9999端口,显示是http服务,使用了nginx 1.10.3 ┌──(kali㉿kali)-[~/HTB/Frolic] └─$ nmap -sC -sV -oA nmap -Pn 10.10.10.111 Starting Nmap 7.93 ( http…

美国安规测试UL 60335-2-3 安全标准家用和类似用途电器安全第 2-3 部分:电熨斗的特殊要求

UL 60335-2-3 安全标准家用和类似用途电器安全第 2-3 部分:电熨斗的特殊要求 本 UL 标准基于 IEC 出版物 60335-2-3:6.1 版,家用和类似用途电器-安全-第 2-3 部分:电熨斗的特殊要 求。 IEC 出版物 60335-2-3 版权归 IEC 所有。 本版本的发布是为了满足 UL 标准政…

如何为数据保护加上“安全锁”?

伴随着数字经济的日趋活跃,数据安全和隐私保护成为了各国政府和企业都十分重视的问题,纷纷加强了数据安全防护。但实际上,近几年数据泄露问题接连不断,虽然没有造成严重的后果,但也足以证明目前数据安全防护的紧迫性。…

【JAVA】concurrentHashMap和HashTable有什么区别

🍎个人博客:个人主页 🏆个人专栏:JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 同步性质: 性能: 允许空键值(Allow Nulls): 迭代器(Iter…

用户态与内核态切换

随笔记录 目录 1. 切换方式 2. 案例介绍 1. 切换方式 1. 用户态切内核态: 用户态切换到内核态的唯一途径——>中断/异常/陷入(陷入又可称作系统调用)2. 内核态切用户态: 内核态切换到用户态的途径——>设置程序状态字 PSW注:CPU中有…

使用curl命令在Linux上进行HTTP请求

在Linux系统中,curl是一个非常强大的命令行工具,用于发送各种类型的HTTP请求。通过简单的命令,你可以发送GET、POST、PUT、DELETE等请求,以及设置请求头、处理响应等。以下是一些使用curl进行HTTP请求的常见用法和示例。 1. 发送…

Unity中URP下实现深度贴花

文章目录 前言一、场景设置二、实现思路1、通过深度图求出像素所在视图空间的Z值2、通过模型面片的求出像素在观察空间下的坐标值3、结合两者求出 深度图中像素的 XYZ值4、再将此坐标转换到模型的本地空间,把XY作为UV来进行纹理采样 三、URP下实现1、通过深度图求出…

专业课120+总分380+海南大学838信号与系统考研经验分享-电子信息,信息与通信,人工智能,生物医学

今年专业课120,总分380顺利被海大录取,总结一下这一年来的复习经验,希望对大家复习有借鉴。特别提醒这两年专业课海南大学838信号与系统难度比较大,还考察了IDTFT,DTFT等,对离散域的考察颇多,不…