爬虫 + 自动化利器 selenium 之自学成才篇(二)_爬虫可以加自动化吗

  • find_elements_by_link_text()
  • find_elements_by_partial_link_text()

这里以 CSDN 首页的一个 博客专家栏 为例。
在这里插入图片描述
下面使用 find_elements_by_xpath 来定位三位专家的名称。
在这里插入图片描述
这是专家名称部分的页面代码,不知各位有没有想到如何通过 xpath 定位这一组专家的名称呢?

from selenium import webdriver

# 设置无头浏览器
option = webdriver.ChromeOptions()
option.add_argument('--headless')

driver = webdriver.Chrome(options=option)
driver.get('https://blog.csdn.net/')

p_list = driver.find_elements_by_xpath("//p[@class='name']")
name = [p.text for p in p_list]
name

切换操作

窗口切换

selenium 操作页面的时候,可能会因为点击某个链接而跳转到一个新的页面(打开了一个新标签页),这时候 selenium 实际还是处于上一个页面的,需要我们进行切换才能够定位最新页面上的元素。

窗口切换需要使用 switch_to.windows() 方法。

首先我们先看看下面的代码。

代码流程:先进入 【CSDN首页】,保存当前页面的句柄,然后再点击左侧 【CSDN官方博客】跳转进入新的标签页,再次保存页面的句柄,我们验证一下 selenium 会不会自动定位到新打开的窗口。

from selenium import webdriver

handles = []
driver = webdriver.Chrome()
driver.get('https://blog.csdn.net/')
# 设置隐式等待
driver.implicitly_wait(3)
# 获取当前窗口的句柄
handles.append(driver.current_window_handle)
# 点击 python,进入分类页面
driver.find_element_by_xpath('//\*[@id="mainContent"]/aside/div[1]/div').click()
# 获取当前窗口的句柄
handles.append(driver.current_window_handle)

print(handles)
# 获取当前所有窗口的句柄
print(driver.window_handles)

在这里插入图片描述
可以看到第一个列表 handle 是相同的,说明 selenium 实际操作的还是 CSDN首页 ,并未切换到新页面。
下面使用 switch_to.windows() 进行切换。

from selenium import webdriver

handles = []
driver = webdriver.Chrome()
driver.get('https://blog.csdn.net/')
# 设置隐式等待
driver.implicitly_wait(3)
# 获取当前窗口的句柄
handles.append(driver.current_window_handle)
# 点击 python,进入分类页面
driver.find_element_by_xpath('//\*[@id="mainContent"]/aside/div[1]/div').click()
# 切换窗口
driver.switch_to.window(driver.window_handles[-1])
# 获取当前窗口的句柄
handles.append(driver.current_window_handle)

print(handles)
print(driver.window_handles)

在这里插入图片描述
上面代码在点击跳转后,使用 switch_to 切换窗口,window_handles 返回的 handle 列表是按照页面出现时间进行排序的,最新打开的页面肯定是最后一个,这样用 driver.window_handles[-1] + switch_to 即可跳转到最新打开的页面了。

那如果打开的窗口有多个,如何跳转到之前打开的窗口,如果确实有这个需求,那么打开窗口是就需要记录每一个窗口的 key(别名) 与 value(handle),保存到字典中,后续根据 key 来取 handle

表单切换

很多页面也会用带 frame/iframe 表单嵌套,对于这种内嵌的页面 selenium 是无法直接定位的,需要使用 switch_to.frame() 方法将当前操作的对象切换成 frame/iframe 内嵌的页面。

switch_to.frame() 默认可以用的 idname 属性直接定位,但如果 iframe 没有 idname ,这时就需要使用 xpath 进行定位。下面先写一个包含 iframe 的页面做测试用。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
 div p {
 color: #red;
 animation: change 2s infinite;
 }
 @keyframes change {
 from {
 color: red;
 }
 to {
 color: blue;
 }
 }
 </style>
</head>

<body>
    <div>
        <p>公众号:Python新视野</p>
        <p>CSDN:Dream丶Killer</p>
        <p>微信:python-sun</p>
    </div>
    <iframe src="https://blog.csdn.net/qq\_43965708" width="400" height="200"></iframe>
<!-- <iframe id="CSDN\_info" name="Dream丶Killer" src="https://blog.csdn.net/qq\_43965708" width="400" height="200"></iframe> -->
</body>
</html>

在这里插入图片描述

现在我们定位红框中的 CSDN 按钮,可以跳转到 CSDN 首页。

from selenium import webdriver
from pathlib import Path


driver = webdriver.Chrome()
# 读取本地html文件
driver.get('file:///' + str(Path(Path.cwd(), 'iframe测试.html')))

# 1.通过id定位
driver.switch_to.frame('CSDN\_info')
# 2.通过name定位
# driver.switch\_to.frame('Dream丶Killer')
# 通过xpath定位
# 3.iframe\_label = driver.find\_element\_by\_xpath('/html/body/iframe')
# driver.switch\_to.frame(iframe\_label)

driver.find_element_by_xpath('//\*[@id="csdn-toolbar"]/div/div/div[1]/div/a/img').click()

这里列举了三种定位方式,都可以定位 iframe
请添加图片描述

弹窗处理

JavaScript 有三种弹窗 alert(确认)、confirm(确认、取消)、prompt(文本框、确认、取消)。

处理方式:先定位(switch_to.alert自动获取当前弹窗),再使用 textacceptdismisssend_keys 等方法进行操作

方法描述
text获取弹窗中的文字
accept接受(确认)弹窗内容
dismiss解除(取消)弹窗
send_keys发送文本至警告框

这里写一个简单的测试页面,其中包含三个按钮,分别对应三个弹窗。

<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
    <button id="alert">alert</button>
    <button id="confirm">confirm</button>
    <button id="prompt">prompt</button>

    <script type="text/javascript">
 const dom1 = document.getElementById("alert")
 dom1.addEventListener('click', function(){
 alert("alert hello")
 })

 const dom2 = document.getElementById("confirm")
 dom2.addEventListener('click', function(){
 confirm("confirm hello")
 })

 const dom3 = document.getElementById("prompt")
 dom3.addEventListener('click', function(){
 prompt("prompt hello")
 })
 </script>
</body>
</html>

在这里插入图片描述
下面使用上面的方法进行测试。为了防止弹窗操作过快,每次操作弹窗,都使用 sleep 强制等待一段时间。

from selenium import webdriver
from pathlib import Path
from time import sleep


driver = webdriver.Firefox()
driver.get('file:///' + str(Path(Path.cwd(), '弹窗.html')))

sleep(2)

# 点击alert按钮
driver.find_element_by_xpath('//\*[@id="alert"]').click()
sleep(1)
alert = driver.switch_to.alert
# 打印alert弹窗的文本
print(alert.text)
# 确认
alert.accept()

sleep(2)

# 点击confirm按钮
driver.find_element_by_xpath('//\*[@id="confirm"]').click()
sleep(1)
confirm = driver.switch_to.alert
print(confirm.text)
# 取消
confirm.dismiss()

sleep(2)

# 点击confirm按钮
driver.find_element_by_xpath('//\*[@id="prompt"]').click()
sleep(1)
prompt = driver.switch_to.alert
print(prompt.text)
# 向prompt的输入框中传入文本
prompt.send_keys("Dream丶Killer")
sleep(2)
prompt.accept()

'''输出
alert hello
confirm hello
prompt hello
'''

请添加图片描述

注:细心地读者应该会发现这次操作的浏览器是 Firefox ,为什么不用 Chrome 呢?原因是测试时发现执行 promptsend_keys 时,不能将文本填入输入框。尝试了各种方法并查看源码后确认不是代码的问题,之后通过其他渠道得知原因可能是 Chrome 的版本与 selenium 版本的问题,但也没有很方便的解决方案,因此没有继续深究,改用 Firefox 可成功运行。这里记录一下我的 Chrome 版本,如果有大佬懂得如何在 Chrome 上解决这个问题,请在评论区指导一下,提前感谢!
selenium:3.141.0
Chrome:94.0.4606.71

未完待续~


⭐️往期精彩,不容错过⭐️

总结篇
❤️两万字,50个pandas高频操作【图文并茂,值得收藏】❤️
❤️吐血总结《Mysql从入门到入魔》,图文并茂(建议收藏)❤️

工具篇
⭐️Python实用小工具之制作酷炫二维码(有界面、附源码)⭐️
❤️Python实用工具之制作证件照(有界面、附源码)❤️
❤️女朋友桌面文件杂乱无章?气得我用Python给她做了一个文件整理工具❤️

更多有趣的文章及干货,尽在

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。

三、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值