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…

基于kafka_exporterprometheusgrafana的kafka监控实现

一、安装配置kafka_exporter 下载kafka_exporter wget http://*.*.*.45:10000/prometheus/kafka_exporter-1.4.2.linux-amd64.tar.gz tar -zxcf kafka_exporter-1.4.2.linux-amd64.tar.gz启动kafka_exporter ./kafka_exporter --kafka.server*.*.*.77:8423 --kafka.server*.…

【Java面试题】char 和 varchar 的区别

1. 最大长度 char 最大长度是 255字符,而 varchar 最大长度是 65535 个字节。 2.定长与可变长 char 是定长的,不足的部分用隐藏空格填充,而 varchar 是不定长的。 3.空间使用 char 会浪费空间,因为其长度固定,所以…

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

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

机器学习-决策树

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

Unity插件开发笔记

插件特点,无需运行可进行编译。 分为3大类插件:菜单项相关操作、自定义Inspector检视面板、自定义操作界面。 一.菜单项相关操作的插件分为4种:包含MenuItem菜单项插件、AddComponentMenu组件菜单插件、ContextMenu上下文菜单插件、Require…

[BUG] docker: unknown server OS: .

前言 我在运行docker时候,使用 docker run 出现了这样的bug 解决 可以先查看 docker images -a,然后提示我说 permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2F…

【我的RUST库】get_local_info 0.2.0发布

get_local_info是一个获取linux本地信息的Rust三方库,其目标是降低获取本地linux系统信息的难度。支持银河麒麟10、UOS、鸿蒙等国产系统。 项目维护:长期 当前功能: 1.网络功能 1.1.获取网络接口信息 1.2 获取活动网卡信息:网…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux网络编程第二天-tcp编程练习(物联技术666)

点赞+关注,功德无量。更多配套资料,欢迎私信。 网盘链接:百度网盘 请输入提取码 WebServer编程: -------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #i…

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

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

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

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

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

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

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

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

sqlite3 jdbc 只读模式

sqlite3 jdbc 只读 无效方法: “jdbc:sqlite:/bal/work_home/fn.db?readonlytrue” 导致 fn.db?readonlytrue 会被当成是数据库文件名 “jdbc:sqlite:/bal/work_home/fn.db?jdbc.explicit_readonlytrue” 参考了pragmaReadOnly sqlite3 jdbc 只读 有效方法 举例 package…

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

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

Linux硬盘挂载

1. 查看磁盘分区情况 执行命令 sudo fdisk -l执行结果 Disk /dev/sda: 171.8 GB, 171798691840 bytes, 335544320 sectors Units sectors of 1 * 512 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 byte…

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

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

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

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