【Python爬虫】Selenium使用

安装配置教程自行搜索

所用驱动chromedriver应与chrome浏览器版本相对应

pip install selenium

笔者selenium所用版本为4.11.2,新旧版之间会有差别

from selenium import webdriver
driver = webdriver.Chrome()

实例化driver对象后,driver对象有一些常用的属性和方法

driver.page_source #当前标签页浏览器渲染之后的网页源代码
driver.current_url #当前标签页的url
driver.close()     #关闭当前标签页,如果只有一个标签页则关闭整个浏览器
driver.quit()      #关闭浏览器
driver.forward()   #页面前进
driver.back()      #页面后退
driver.refrash()   #页面刷新
driver.save_screenshot("img_name") #页面截图

我们使用Selenium时会觉得浏览器加载很慢,这和它的页面加载策略有关

Selenium的页面加载策略(pageLoadStrategy)

本段摘自:https://blog.csdn.net/momoda118/article/details/120624777

  1. normal:等待整个页面加载完毕再开始执行操作(默认为此)
  2. eager:等待整个dom树加载完成,即DOMContentLoaded这个事件完成,也就是只要 HTML完全加载和解析完毕就开始执行操作。放弃等待图片、样式、子帧的加载。
  3. none:等待html下载完成,哪怕还没开始解析就开始执行操作。

加载策略设置为eager

配置代码如下:

chrome_options = Options()
chrome_options.page_load_strategy = 'eager'
driver = webdriver.Chrome(options=chrome_options)

加载策略设置为none

加载策略设置为none,并引入retry做重试(目的是为了防止报错,当然设置隐式等待也可,但没retry稳妥)可以只用2s左右就能执行完成,完整代码如下:

import datetime
from retrying import retry  # 需第三方库,需pip进行安装
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By@retry(wait_fixed=10, stop_max_attempt_number=1)
def click(path):driver.find_element(By.XPATH, path).click()chrome_options = Options()
chrome_options.page_load_strategy = 'none'
driver = webdriver.Chrome(options=chrome_options)
start_time = datetime.datetime.now()
driver.get('https://www.iqiyi.com/')
click('//*[@id="block-C"]/div/div/div/div[1]/div[1]/div/div[1]/div/div/a/span[2]')
end_time = datetime.datetime.now()
print(end_time - start_time)

元素定位

本段参考:https://blog.csdn.net/qq_18298049/article/details/117136214

element = driver.find_element(By.ID, 'kw')   # 通过ID定位搜索框element = driver.find_element(By.NAME, 'wd')   # 通过name定位搜索框element = driver.find_element(By.CLASS_NAME, 's_ipt')   # 获取百度首页搜索框element = driver.find_element(By.TAG_NAME, 'input')  # 查找标签名称是input的元素element = driver.find_element(By.LINK_TEXT, '贴吧')   # 定位贴吧element = driver.find_element(By.PARTIAL_LINK_TEXT, '贴')   # 定位贴吧

头尾匹配写法:其中,头尾匹配可以是部分字符,部分匹配需要是按空格分隔的完整字符。

条件htmlvalues 写法1 (头部匹配)values 写法2 (尾部匹配)values 写法3 (部分匹配)
class< button class=“el-button el-button–primary”>‘[class^=“el-button”]’‘[class$=“–primary”]’‘[class~=“el-button”]’

css selector

element = driver.find_element(By.CSS_SELECTOR, '#kw')   # #kw id选择器
element = driver.find_element(By.CSS_SELECTOR, '.s_ipt')   # .s_ipt class选择器
element = driver.find_element(By.CSS_SELECTOR, 'form #kw')   # 后代元素选择器
element = driver.find_element(By.CSS_SELECTOR, "input[name='wd']")   # 属性值定位选择器# 同时包含两个条件
# 包含type='text'与maxlength='50'两个条件的元素,语法上不需要and进行连接
driver.find_element(By.CSS_SELECTOR, '[type="text"][maxlength="50"]')
# 包含一个条件且不包含另一条件
# 包含type='text'且不包含maxlength='50'的元素,语法上使用:not()进行连接
driver.find_element(By.CSS_SELECTOR, '[type="text"]:not([maxlength="50"])')

xpath

相对路径

// #查找页面根元素
//input #查找页面上所有的input元素
//form[1]/input #查找页面上第一个form元素内的直接子input元素(即只包括form元素的下一级input元素,使用绝对路径表示,单/号)
//form[1]//input #查找页面上第一个form元素内的所有子input元素(只要在form元素内的input都算,不管还嵌套了多少个其他标签,使用相对路径表示,双//号)
//form[1] #查找页面上第一个form元素
//form[@id='loginForm'] #查找页面上id为loginForm的form元素
//input[@name='username'] #查找页面上具有name属性为username的input元素
//form[@id='loginForm']/input[1] #查找页面上id为loginForm的form元素下的第一个input元素
//input[@name='continue'][@type='button'] #查找页面具有name属性为contiune并且type属性为button的input元素
//form[@id='loginForm']/input[4] #查找页面上id为loginForm的form元素下第4个input元素

写法为:element = driver.find_element(By.XPATH, '路径')

绝对路径

调试模式找到元素右键复制

不建议写绝对路径!!!

定位模糊匹配

contains关键字://a[contains(@href, ‘logout’)]

寻找页面中href属性值包含有logout这个单词的所有a元素

start-with关键字://a[starts-with(@name, ‘start)])

寻找name属性以start开头的a元素。其中@后面的name可以替换成元素的任意其他属性

text关键字://*[text()=’确定’]

一个简单粗暴的定位方式,无需知道属于什么标签元素,常用于纯文字查找,也可用于链接元素文本查找

//a[contains(text(), ’退出’)]

用于知道超链接上显示的部分或全部文本信息时

find_element和find_elements

  • find_element返回匹配到的第一个标签对象;find_elements返回列表
  • find_element匹配不到抛出异常;find_elements匹配不到返回空列表

元素操作

示例1:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import timechrome_options = Options()
chrome_options.page_load_strategy = 'eager'
service = Service('chromedriver.exe路径')driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://www.baidu.com")
driver.find_element(By.ID, 'kw').send_keys('python')
driver.find_element(By.ID, 'su').click()
time.sleep(5)
driver.close()

示例2:

el_list: list = driver.find_elements(By.XPATH, "/html/body/div[6]/div[2]/ul/li/div[2]/h2/a")
for el in el_list:print(el.text)print(el.get_attribute('href'))

标签页(窗口)切换

我们在使用浏览器的时候,会自动转到新的标签页,但selenium不会这样,我们需要进行操作来实现

利用窗口句柄切(指向标签页对象的标识)换到句柄指向的标签页

driver.get("url")
time.sleep(3)
print(driver.current_url) #获取当前页面的url
print(driver.window_handles) #获取当前所有存在的窗口句柄,多个句柄以列表方式存储
driver.find_element(By.XPATH, "/html/body/div[6]/div[2]/ul/li[1]/div[2]/h2").click()
print(driver.current_url)
print(driver.window_handles)
time.sleep(3)
driver.switch_to.window(driver.window_handles[-1]) #切换至新窗口
print(driver.current_url)
time.sleep(3)
driver.close() #关闭当前窗口
driver.switch_to.window(driver.window_handles[0]) #切换至原窗口
print(driver.current_url)

iframe切换

<iframe src="1.html" id="hogwarts_id" name="hogwarts_name"></iframe>

实现:

# index:传入整型的参数,从 0 开始,这里的 0 就是第一个 frame
driver.switch_to.frame(0)
#id:iframe 的 id
driver.switch_to.frame("hogwarts_id")
#name: iframe 的 name
driver.switch_to.frame("hogwarts_name")
#WebElement: 传入 `selenium.webelement` 对象
driver.switch_to.frame(driver.find_element(By.TAG_NAME,"iframe"))

在切换页面之后,如果还想操作原页面,则可以使用:

driver.switch_to.default_content()

嵌套多层iframe的切换:

<html><iframe src="a.html" id="frame1"><iframe src="b.html" id="frame2" ><input id="kw" / ></iframe></iframe>
</html>

多层嵌套的情况下,如果要从主界面切换到第二层iframe,则需要一层一层的切换进去,即先切换到frame1,再切换到frame2,而不是直接切换进入frame2

driver.switch_to.frame("frame1")
driver.switch_to.frame("frame2")

selenium还提供了一个切换到父frame的方法,比如我们切换到frame2之后,要想切换到frame1操作,则不需要先切回主界面再切换到frame,而是使用如下方法:

driver.switch_to.parent_frame()

需要注意的是,如果当前已经是主页面,则使用此方法无效

cookies操作

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import timechrome_options = Options()
chrome_options.page_load_strategy = 'eager'
service = Service('chromedriver.exe路径')driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://www.baidu.com")
#print(driver.get_cookies())
#转换为字典格式
cookies = {}
for data in driver.get_cookies():cookies[data['name']] = data['value']
#字典推导式
cookies1= {data['name']: data['value']for data in driver.get_cookies()}
print(cookies)
print(cookies1)
driver.delete_cookie('CookieName') #删除一条cookie
driver.delete_all_cookies() #删除所有cookie

页面等待

强制等待

time.sleep()

缺点:不智能:设置的时间短,元素还没有加载出来;设置的时间长,则会浪费时间

隐式等待

隐式等待针对的是元素定位(设置一次,所有元素定位都会按照设定),隐式等待设置了一个时间,在一段时间内判断元素是否定位成功,如果完成了,就进行下一步;如果在设置的时间内没有定位成功,则会报超时加载

#隐式等待
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import timechrome_options = Options()
chrome_options.page_load_strategy = 'eager'
service = Service('chromedriver.exe路径')driver = webdriver.Chrome(service=service, options=chrome_options)
driver.implicitly_wait(5) #设置隐式等待时间为5秒
driver.get("https://www.baidu.com")
driver.find_element(By.ID, 'kkww') #5秒钟内定位不到元素,报错

显式等待

明确等待某一个元素

每经过多少秒就查看一次等待条件是否达成,如果达成就停止等待,继续执行后续代码;如果没有达成就继续等待直到超过规定的时间后报超时异常

多用于软件测试,想要了解请自行查找

Chrome无界面模式

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import timechrome_options = Options()
chrome_options.page_load_strategy = 'eager'
service = Service('chromedriver.exe路径')
chrome_options.add_argument("--headless")    #添加开启无界面模式的命令
chrome_options.add_argument("--disable-gpu") #添加开启禁用gpu的命令driver = webdriver.Chrome(service=service, options=chrome_options)
driver.get("https://www.baidu.com")
driver.save_screenshot('baidu.png')

配置代理:chrome_options.add_argument("--proxy-server=http://113.254.44.242:8382")

注意:更换ip代理必须重启浏览器

配饰UserAgent:``chrome_options.add_argument(“–user-agent=XXXX”)`

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

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

相关文章

vue(十二) 组件二 动态组件(Component)和异步组件(defineAsyncComponent)

文章目录 组件注册1.全局注册2.局部注册3.组件名格式 动态组件异步组件1.基本使用2.加载与错误状态3.搭配Suspense 组件使用 组件注册 一个 Vue 组件在使用前需要先被“注册”&#xff0c;这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式&#xff1a;全局注册…

git拉取项目前需要操作哪些?

1.输入 $ ssh-keygen -t rsa -C "秘钥说明" 按enter键 2.出现 ssh/id_rsa&#xff1a;(输入也可以不输入也可以) 然后按enter键 3.出现empty for no passphrase&#xff1a;(输入也可以不输入也可以) 然后按enter键 4.出现same passphrase again: (输入也可以不输入也…

程序员如何减肥

目录 基本的生化知识减肥三板斧关于减肥药 基本的生化知识 人体供能顺序。是糖原——脂肪——蛋白质&#xff0c;只有先将肝糖原耗尽&#xff0c;机体才会动用脂肪。因为糖原分解靠的是三羧酸循环&#xff0c;脂肪分解靠的是脂肪动员和丙酮分解。如果一个人动用蛋白质来供能&a…

linux下直接使用别人的anaconda环境,copy别人环境

1.直接使用别人的anaconda安装环境 source /home/XXX/anaconda3/bin/activate conda activate labelme 2.copy anaconda环境 cp -r /home/XXX/anaconda3/envs/x-anylabeling /home/YYY/anaconda3/envs conda config --append envs_dirs /home/YYY/anaconda3/envs conda activa…

20240516-Flyme AIOS 特种兵发布会

目录 1 Flyme AIOS 2 路演功能 2.1 拖拽流转 2.2 任务剧本自定义 2.3 智能体商店 2.4 实况通知 2.5 AI壁纸 3 MYVU 3.1 翻译功能 3.2 AR导航-骑行 3.3 AI语音转文字-科技向善 3.4 Flyme AR-提词器增强 1 Flyme AIOS 1&#xff09;目标&#xff1a;All in AI&#…

AI绘图Stable Diffusion,如何无损高清放大图片,保姆级教程建议收藏!

前言 我们在用 stable diffusion 制作AI图片时&#xff0c;默认生成图片的尺寸为512*512&#xff0c;即使是竖图一般也就是512*768&#xff0c;如果再把尺寸设置大一些&#xff0c;就会因为硬件算力不够而造成系统崩溃&#xff0c;今天就来跟大家聊一聊&#xff0c;如何将制作…

RocketMQ-Dashboard 控制台使用详解

1 安装部署 具体部署启动请参考&#xff1a;RocketMQ从安装、压测到运维一站式文档_rocketmq benchmark压测-CSDN博客 RocketMq的dashboard&#xff0c;有运维页面&#xff0c;驾驶舱&#xff0c;集群页面&#xff0c;主题页面&#xff0c;消费者页面&#xff0c;生产者页面&…

[解决]静态方法不能使用泛型

public static Result<T> success(T data){Result<T> result new Result<>(data);result.setCode("200");result.setMsg("success");return result;}会报错&#xff0c;因为静态方法不能使用泛型 解决方法&#xff1a; 在static后加上…

【Kubenetes】边缘计算KubeEdge架构设计详解

文章目录 前言KubeEdge云边通信方式云端架构设计EdgeController:云到边&#xff1a;边到云 DeviceController:云到边边到云 边缘端架构设计EdgedPod的管理部分Pod的监控部分Pod的卷管理Pod的垃圾回收Pod同步管理 MetaMangger从云到边缘的更新 (Update From Cloud To Edge)从边缘…

入门篇:Kafka基础知识·

目录 一、Kafka简介 二、Kafka核心组件 三、Kafka安装与配置 1.下载与解压 2.配置环境变量 3.配置server.properties 4.启动Kafka服务 四、Kafka基本操作 1.创建Topic 2.查看Topic列表 3.发送消息 4.接收消息 五、Kafka进阶使用 1.消息持久化与存储 2.消息顺序与…

react 使用WebAssembly实战

在React中使用WebAssembly&#xff08;WASM&#xff09;的示例可以通过以下步骤实现&#xff1a; 1. 准备WebAssembly模块 首先&#xff0c;确保你有一个已编译的WebAssembly模块&#xff08;.wasm文件&#xff09;。如果你还没有&#xff0c;可以通过Emscripten等工具将C/C代…

Covalent长期数据设施,支持基于 “blob” 、总锁仓54亿美元的L2

Covalent Network&#xff08;CQT&#xff09;是领先的历史数据可用性网络&#xff0c;通过其在 Web3 中超过 225 个区块链上的结构化数据基础设施&#xff0c;为数千名客户和开发人员提供支持。Covalent Network&#xff08;CQT&#xff09;正在与未来以太坊的进步需求相匹配&…

SQL慢查询学习篇

https://www.cnblogs.com/isyues/p/17733015.html 1. 对扫到的SQL慢查询语句执行 explain explain select task_id, channel, count(task_id) as count from tablename where send_time > "2024-05-10 16:13:59" and send_time < "2024-05-14 16:13:59…

api接口、api文档、api调试、api测试

应用程序接口是一组定义、程序及协议的集合&#xff0c;通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过调用 API 函数对应用程序进行开发&#xff0c;可以减轻编程任务。 API 同时也是一种中间件&#xff0c;为各种不同平台提供数…

展馆展厅设计施工流程

1、需求分析和确定&#xff1a; 与客户沟通&#xff0c;了解客户需求&#xff0c;对展馆展厅的用途、面积、功能、展品特点等进行分析&#xff0c;并确定设计方案。 2、方案设计 根据需求确定设计方案&#xff0c;包括平面布局、展品陈列、展示方式、照明等。设计师需要提供设计…

Linux-yum命令使用详解

目录 一、yum 命令 二、本地yum源配置 1、把光驱挂载到临时挂载点 2、定义本地yum源 3、清空并加载 4、配置国内yum源 5、配置epel源 三、安装软件 一、yum 命令 yum list installed 找出系统上已安装的包 yum list installed > fileName 找出系统上已安装包的列表…

如何在Spring启动的时候执行一些操作

如何在Spring启动的时候执行一些操作 在Spring启动的时候执行一些操作有多种方式。你可以通过实现ApplicationRunner或者CommandLineRunner接口&#xff0c;在Spring Boot应用程序启动后执行特定操作。另外&#xff0c;你也可以使用PostConstruct注解&#xff0c;在Spring Bea…

【考研数学】张宇《1000题》强化阶段正确率多少算合格?

张宇1000题真的很练人心态.... 基础不好&#xff0c;建议别碰1000题 基础好&#xff0c;1000题建议在两个月以内刷完 如果自己本身在基础阶段学的比较水&#xff0c;自己的薄弱点刷了一小部分题没有针对性完全解决&#xff0c;转身去刷1000题就会发现&#xff0c;会的题目刷…

Electron - 跨平台桌面应用开发工具的使用总结

文章目录 一、使用electron-vite新建项目二、目录结构三、渲染进程调用主进程1、方式一 —— 允许有返回值 src/main/index.js src/preload/index.js src/renderer/index.html 2、方式二—— 允许有返回值 (推荐写法) src/main/index.js src/preload/index.js src/renderer/ind…

shell脚本-重定向与管道符

一、重定向 因为shell脚本有着批量操作的特殊性&#xff0c;大部分操作处于后台执行&#xff0c;不需要用户进行干预&#xff0c;所以提取、过滤并执行信息十分需要重定向和管道。重定向的意思是不输出到默认设备上&#xff0c;而是输出到你指定的位置&#xff08;文件、其他输…