当前位置: 首页 > news >正文

【爬虫】5.6 Selenium等待HTML元素

目录

任务目标

创建Ajax网站

创建服务器程序

Selenium XX 等待

1. Selenium强制等待

2. Selenium隐性等待

3. Selenium循环等待

4. Selenium显示等待

等待方法


任务目标

  • 在浏览器加载网页的过程中,网页的有些元素时常会有延迟的现象,在HTML元素还没有准备好的情况下去操作这个HTML元素必然会出现错误,这个时候Selenium需要等待HTML元素。例如:上节实例中出现的select的下拉框元素,选项填充需要执行JavaScript脚本
  • 我们来学习如果使用Selenium等待延迟的HTML元素并最终爬取元素的数据。

创建Ajax网站

phone.html 如下:

注:phone.html 文件要位于 templates 这个目录下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><form name="frm" action="/"><div><span id="msg"></span><label for="xmark"></label><select id="xmark"></select></div><input type="submit" value="提交" id="submit" disabled="true"></form>
</body>
<script>function loadMarks(){var http=new XMLHttpRequest(); http.open("get","/marks",true);http.send(null);http.onreadystatechange=function(){// onreadystatechange存储函数,每当 readyState 属性改变时,就会触发调用该函数。// readystate存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。// 0: 请求未初始化    1: 服务器连接已建立     2: 请求已接收    3: 请求处理中    4: 请求已完成,且响应已就绪// status,200(OK),404(未找到页面)if (http.readyState===4 && http.status===200){ //请求完成并且成功返回var xmark=document.getElementById("xmark"); var xcolor=document.getElementById("xcolor"); marks=eval("("+http.responseText+")");// JS中将JSON的字符串解析成JS对象格式for(var i=0;i<marks.length;i++) xmark.options.add(new Option(marks[i],marks[i])); document.getElementById("submit").disabled=false;document.getElementById("msg").innerHTML="品牌";}};}loadMarks();
</script>
</html>

创建服务器程序

服务器server.py程序如下:

import flask
import json
import timeapp = flask.Flask(__name__)@app.route("/")
def index():return flask.render_template("phone.html")@app.route("/marks")
def loadMarks():time.sleep(1)marks = ["华为", "苹果", "三星"]return json.dumps(marks)  # 将JSON的对象格式转化成str格式app.run()

模拟网站结果如下:


Selenium XX 等待

1. Selenium强制等待

必须等待的时间,缺点:不能准确把握需要等待的时间(有时操作还未完成,等待就结束了,导致报错;有时操作已经完成了,但等待时间还没有到,浪费时间),如果在用例中大量使用,会浪费不必要的等待时间,影响测试用例的执行效率。

from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
driver.get("http://127.0.0.1:5000")# 设置强制等待1.5秒,
time.sleep(1.5)marks = driver.find_elements(By.XPATH, "//select/option")
print("品牌数量:", len(marks))
for mark in marks:print(mark.text)
form = driver.find_element(By.XPATH, "//form")
print(form.get_attribute("innerHTML").strip())
time.sleep(5)
driver.close()

2. Selenium隐性等待

该方法是浏览器对象调用的方法,即设置浏览器打开网页均等待的时长, 同样如果设置的隐性等待时间不够长, 还是爬取不到需要的数据。

from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()# 设置隐性加载时间1.5秒,即网页在加载时最长等待 seconds 秒
driver.implicitly_wait(1.5)driver.get("http://127.0.0.1:5000")
marks = driver.find_elements(By.XPATH, "//select/option")
print("品牌数量:", len(marks))
for mark in marks:print(mark.text)
form = driver.find_element(By.XPATH, "//form")
print(form.get_attribute("innerHTML").strip())
time.sleep(5)
driver.close()

3. Selenium循环等待

循环等待 实际上这个爬虫程序能否爬到数据的关键是<select>中是否已经出现了<option>元素,我们可以设置一个循环来判断是否有<option>元素

from selenium import webdriver
from selenium.webdriver.common.by import By
import timedriver = webdriver.Chrome()
try:driver.get("http://127.0.0.1:5000")waitTime = 0while waitTime < 10:marks = driver.find_elements(By.XPATH, "//select/option")if len(marks) > 0:breaktime.sleep(0.5)waitTime += 0.5if waitTime >= 10:raise Exception("Waiting time out")marks = driver.find_elements(By.XPATH, "//select/option")print("品牌数量:", len(marks))for mark in marks:print(mark.text)form = driver.find_element(By.XPATH, "//form")print(form.get_attribute("innerHTML").strip())
except Exception as err:print(err)
time.sleep(5)
driver.close()

循环等待 实际上这个爬虫程序能否爬到数据的关键是<select>中是否已经出现了<option>元素,我们可以设置一个循环来判断是否有<option>元素。 这个程序中使用 waitTime 变量来构造一个循环,它最长等待 10 秒,每间隔 0.5 秒就检查一次<select>中是否有<option>存在,如果找到了<option>元素就退出等待循环,不然就继续等待直到<option>出现为止,如果 10 秒内还没有出现据抛出异常。

4. Selenium显示等待

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import Bydriver = webdriver.Chrome()
try:driver.get("http://127.0.0.1:5000")# 显示等待locator = (By.XPATH, "//select/option")WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located(locator))marks = driver.find_elements(By.XPATH, "//select/option")print("品牌数量:", len(marks))for mark in marks:print(mark.text)form = driver.find_element(By.XPATH, "//form")print(form.get_attribute("innerHTML").strip())
except Exception as err:print(err)

构造一个定位元素的 locator 的对象,例如通过 XPath 的方法定位<select>中的<option>元素:

locator=(By.XPATH,"//select/option")

使用 WebDriverWait 构造一个实例,调用 until 方法:

WebDriverWait(driver, 10,0.5).until(EC.presence_of_element_located(locator))

这条语句的含义是等待 locator 指定的元素出现,最长等待 10 秒,每间隔 0.5 秒就出现检查一次。如果在 10 秒内出现了该元素就是结束等待,否则就抛出一个异常,默认抛出异常为:NoSuchElementException。

这种等待的优点:等待判断准确,不会浪费多余的等待时间,在实际中使用可以提高执行效率。


等待方法

1. EC.presence_of_element_located(locator)

这种形式是 等待 locator指定的元素 出现 ,也就是HTML文档中建立起了这个元素。

2. EC.visibility_of_element_located(locator)

这种形式是 等待 locator指定的元素 可见 ,注意元素出现时未见得可见,

例如:

<select id="xmark" style="display:none">...</select>

那么元素<select>是出现的但是不可见。

3. EC.element_to_be_clickable(locator)

这种形式是 等待 locator指定的元素 可以被点击

例如,在爬虫程序中等待 <input type="submit"> 按钮可用被点击:

locator = (By.XPATH, "//input[@type='submit']")

WebDriverWait(driver, 10,0.5).until(EC.element_to_be_clickable(locator))

或者等待 <option> 是否可以被点击: locator = (By.XPATH, "//select/option") WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))

使用这两种方法都可以爬取到手机品牌数据。

但是注意使用: locator = (By.XPATH, "//select") WebDriverWait(driver,10,0.5).until(EC.element_to_be_clickable(locator))

是等待<select>是否可以点击,这个元素就是没有<option>时也是可以点击的,因此用这个等待是爬取不到手机的品牌数据的。

4. EC.element_located_to_be_selected(locator)

这种形式是 等待 locator指定的元素 可以被选择,可以被选择的元素一般是<select>中的选项<option>、输入的多选框 <input type="checkbox"> 以及输入的单选框 <input type="radio">等元素。

locator = (By.XPATH, "//select/option")

WebDriverWait(driver, 10,0.5).until(EC.element_located_to_be_selected(locator))

同样能爬取到手机的品牌数据。

但是使用下列是不行的:

locator = (By.XPATH, "//input[@type='submit']")

WebDriverWait(driver,   10,0.5).until(EC.element_located_to_be_selected(locator))

因为这样的 <input type='submit'> 是怎么样也不可以选择的。

5. EC.text_to_be_present_in_element(locator,text)

这种形式是等待 locator 指定的元素的文本中包含指定的text文本,例如爬虫程序中使用下列的等待:

locator = (By.ID, "msg")

WebDriverWait(driver, 10,0.5).until(EC.text_to_be_present_in_element(locator,"品"))

即等待<span id="msg">......</span>元素中的文本包含"品"字,由于在<option>出现后设置文本是"品牌",因此爬虫程序可以爬取到手机品牌数据。


下一篇文章:实验项目一:【文本反爬网站的分析和爬取】

相关文章:

【爬虫】5.6 Selenium等待HTML元素

目录 任务目标 创建Ajax网站 创建服务器程序 Selenium XX 等待 1. Selenium强制等待 2. Selenium隐性等待 3. Selenium循环等待 4. Selenium显示等待 等待方法 任务目标 在浏览器加载网页的过程中&#xff0c;网页的有些元素时常会有延迟的现象&#xff0c;在HTML元素…...

0102阿里云配置3台ECS服务器-大数据学习

文章目录 1 前言1 配置VPC和子网2 创建安全组3 创建云服务器ECS3.1 规划配置3.2 配置 4 xshell连接服务器5 配置基础环境5.1 主机名映射5.2 ssh免密登录5.3 jdk 6 问题集6.1 Permission denied (publickey,gssapi-keyex,gssapi-with-mic).6.2 用tar解压文件出现错误Not found i…...

android 输入法demo

背景&#xff1a; 一个简单的android输入法demo&#xff0c;支持输入png、gif&#xff0c;jpeg、webp等格式。 此示例演示如何编写一个应用程序&#xff0c;该应用程序接受使用 Commit Content API 从键盘发送的丰富内容&#xff08;例如图像&#xff09;。 用户通常希望通过表…...

【经验分享】Markdown中如何显示空格和回车

Markdown中如何显示空格和回车 空格 利用html中的空格实体引用&#xff1a; eg&#xff1a; 这是一些 额外的空格。回车&#xff1a; 方法一&#xff1a;在你想要回车的地方连续按两次回车键 方法二&#xff1a;使用<br>标签 eg&#xff1a; 我想显示<br>…...

深入篇【C++】set和map(multiset/multimap)特性总结与使用

深入篇【C】set和map(multiset/multimap&#xff09;特性总结与使用 一.set/multiset总结二.map/multiset总结三.set/map应用 一.set/multiset总结 set是按照一定次序存储元素的容器在set中&#xff0c;元素的value也标识它(value就是key&#xff0c;类型为T)&#xff0c;并且每…...

OpenAI推出ChatGPT企业版,提供更高安全和隐私保障

&#x1f989; AI新闻 &#x1f680; OpenAI推出ChatGPT企业版&#xff0c;提供更高安全和隐私保障 摘要&#xff1a;OpenAI发布了面向企业用户的ChatGPT企业版&#xff0c;用户可以无限制地访问强大的GPT-4模型&#xff0c;进行更深入的数据分析&#xff0c;并且拥有完全控制…...

Linux虚拟机磁盘扩容

Linux虚拟机磁盘扩容 问题起源 在使用linux系统开发时遇到文件无法创建的问题&#xff0c;根据提示发现是磁盘空间不足。 使用df -h查看具体磁盘使用情况。 针对这个问题&#xff0c;有两种解决方案&#xff1a; 使用du -sh ./*可以查看当前工作目录下各文件的占用空间大小…...

【Go 基础篇】Go语言结构体实例的创建详解

在Go语言中&#xff0c;结构体是一种强大的数据类型&#xff0c;允许我们定义自己的复杂数据结构。通过结构体&#xff0c;我们可以将不同类型的数据字段组合成一个单一的实例&#xff0c;从而更好地组织和管理数据。然而&#xff0c;在创建结构体实例时&#xff0c;有一些注意…...

服务器上使用screen的学习记录

服务器上使用screen 训练模型的时候&#xff0c;花费时间是很长的&#xff0c;不可能一直挂在桌面上。所以就想到用screen了。 记录一下简单的操作指令。 创建screen screen -S roof # 新建一个名字为name的窗口&#xff0c;并进入到该窗口中进入后打开环境&#xff0c;运…...

基于Django+node.js+MySQL+杰卡德相似系数智能新闻推荐系统——机器学习算法应用(含Python全部工程源码)+数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境node.js前端环境MySQL数据库 模块实现1. 数据预处理2. 热度值计算3. 相似度计算1&#xff09;新闻分词处理2&#xff09;计算相似度 4. 新闻统计5. API接口开发6. 前端界面实现1&#xff09;运行逻辑2&#xff0…...

2001-2022年全国各区县最低工资数据

2001-2022年全国各区县最低工资数据 1、时间&#xff1a;2001-2022年 2、来源:人社部 3、指标&#xff1a;年份、行政区划代码、地区、所属省份、所属城市、经度、纬度、最低工资-每月、最低工资-小时 4、样本量&#xff1a;5.5万条 5、指标解释&#xff1a;最低工资标准是…...

D357周赛复盘:模拟双端队列反转⭐⭐+贪心

文章目录 2810.故障键盘1.直接用reverse解决2.双端队列 2811.判断能否拆分数组&#xff08;比较巧妙的贪心&#xff09;思路完整版 2812.找出最安全路径2810.故障键盘1.直接用reverse解决2.双端队列 2811.判断能否拆分数组&#xff08;比较巧妙的贪心&#xff09;思路完整版 28…...

大数据项目实战(安装Hive)

一&#xff0c;搭建大数据集群环境 1.3 安装Hive 1.3.1 Hive的安装 1.安装MySQL服务 1&#xff09;检查是否安装MySQL&#xff0c;如安装将其卸载。卸载命令 rpm -qa | grep mysql 2&#xff09;搜索MySQL文件夹&#xff0c;如存在则删除 find / -name mysql rm -rf /etc/s…...

跨屏无界 | ZlongGames 携手 Google Play Games 打造无缝游戏体验

一款经典游戏&#xff0c;会在时间的沉淀中被每一代玩家所怀念&#xff0c;经久不衰。对于紫龙游戏来讲&#xff0c;他们就是这样一群怀揣着创作出经典游戏的初心而聚集在一起的团队&#xff0c;致力于研发出被广大玩家喜爱的作品。 从 2015 年团队成立&#xff0c;到 2019 年走…...

mysql数据文件

提示&#xff1a;mysql相关系列的教程和笔记不断持续更新和完善 文章目录 db.opt 文件FRM 文件MYD 文件MYI 文件IBD 文件和 IBDATA 文件 :ibdata1 ibdata n文件 查看数据文件的位置 获取硬盘中数据存储的位置&#xff1a; SHOW VARIABLES LIKE datadir;db.opt 文件 该文件记录…...

Vue2里监听localstorage里值的变化

有的时候,我们需要根据本地缓存在localstorage里值的变化做出相应的操作,这就需要我们监听localstorage: 首先,我们在src下的libs文件夹下新建一个stroage.js用于重写setItem事件,当使用setItem的时候,触发,window.dispatchEvent派发事件 const Stroage = {// 重写set…...

QSqlDatabase(2)实例,QTableView显示数据库表数据

目录 前言 1、实现的功能 2、具体的代码实现 前言 想了解QSqlDatabase基本知识的&#xff0c;以及增删改查的用法&#xff0c;可以浏览上一篇文章&#xff1a; QSqlDatabase&#xff08;1&#xff09;基本接口&#xff0c;以及(增删改除)的简单实例_Ivy_belief的博客-CSDN…...

vue3 监听props 的变化

再三说明 仅仅个人学习用&#xff0c;不误导别人 我觉得props 会创建对应的属性&#xff0c;去接受这些值&#xff0c;比如传递一个ref的基本值 age props.age age.value 传递一个ref的引用值 person props.person person.value 传递一个reactive的引用值 person props.person…...

Docker容器

1、什么是docker,为什么要使用docker 有了docker,可以获取各种软件的镜像&#xff0c;将软件的镜像下载到linux中&#xff0c;基于这个镜像就能够去启动这个容器&#xff0c;这个容器就是这个镜像的完整运行环境&#xff0c;比如mysql、redis、nginx&#xff0c;还能秒级启动他…...

spring 请求等问题

1.post请求 /*** desc: (gateway主要接收前端请求 &#xff0c; 然后对请求的数据进行验证 &#xff0c; 验证之后请求反向代理到服务器 。*当请求 method 为 GET 时 &#xff0c; 可以顺利通过gateway 。 当请求 method 为 POST 时 &#xff0c; gateway则会报如下错误 。*jav…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...