探索自动化网页交互的魔力:学习 Selenium 之旅【超详细】

"在当今数字化的世界中,网页自动化已经成为了不可或缺的技能。想象一下,您可以通过编写代码,让浏览器自动执行各种操作,从点击按钮到填写表单,从网页抓取数据到进行自动化测试。学习 Selenium,这一功能强大的自动化工具,将为您打开无尽的可能性。在本博客中,您将深入探索 Selenium 的精髓,学习如何构建稳定、高效的自动化脚本,以及如何应用这些技能来提升工作效率、加速开发流程和实现可靠的网页交互。无论您是一名开发人员、自动化工程师还是对网页技术感兴趣的爱好者,本博客将带您踏上一段令人激动的学习之旅,释放出无限的可能性。准备好挑战传统、超越自我,掌握 Selenium,引领网页自动化的未来吗?让我们一起探索吧!"

Selenium

简介

简介
Selenium是一个Web的自动化测试工具,最初是为网站自动化测试而开发的,类型像我们玩游戏用的按键精灵,
可以按指定的命令自动操作,不同是Selenium 可以直接运行在浏览器上,它支持所有主流的浏览器(包括PhantomJS这些无界面的浏览器)。
Selenium 可以根据我们的指令,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。

官网
selenium官网
https://selenium-python.readthedocs.io/index.html
注意
Selenium 自己不带浏览器,不支持浏览器的功能,它需要与第三方浏览器结合在一起才能使用
但是我们有时候需要让它内嵌在代码中运行,所以我们可以用一个叫 PhantomJS 的工具代替真实的浏览器

安装

安装selenium

pip install selenium



安装ChromeDriver
国内源

https://registry.npmmirror.com/binary.html?path=chromedriver/
ChromeDriver
版本号要对应/帮助-关于Google Chrome——>找到对应版本下载——>下载的文件解压到python_version\Scripts

安装Firefox geckodriver
国内源

https://download-installer.cdn.mozilla.net/pub/firefox/releases/
Firefox geckodriver
安装firefox最新版本,添加Firefox可执行程序到系统环境变量。记得关闭firefox的自动更新
将下载的geckodriver.exe 放到path路径下 D:\Python\python_version\

基础知识

基础操作

创建浏览器对象

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
service = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)



打开页面

chrome.get('http://www.baidu.com')



打开本地页面

import os
file_path='file:///'+os.path.abspath('./1.下拉菜单.html')
chrome.get(file_path)



获取页面html源码【换行】

page = chrome.page_source



休眠

from time import sleep
sleep(8)



关闭浏览器

chrome.quit()

操作浏览器

窗口大小

chrome.maximize_window() #窗口最大化
chrome.set_window_size(600, 800) #设置窗口大小



前进和后退

chrome.forward()
chrome.back()

基础定位

定位元素

from selenium.webdriver.common.by import By
chrome.find_element(By.ID,'su')
chrome.find_element(By.XPATH, "//option[@value='10.69']").click()



find_element(type,value)   一个元素
find_elements(type,value)  多个元素
By中参数选择
XPATH【xpath选择器】
ID【id属性】
NAME【name属性 】
CLASS_NAME 【class属性】
LINK_TEXT 【超链接的文本】
PARTIAL_LINK_TEXT = "partial link text"
TAG_NAME = "tag name"
CSS_SELECTOR = "css selector"

操作元素
click 点击对象
send_keys 在对象上模拟按键输入
clear 清除对象的内容,如果可以的话

基础示例

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import Byservice = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
chrome.get('http://www.baidu.com')
sleep(3)
chrome.find_element(By.ID, 'kw').send_keys('CSDN')
sleep(3)
chrome.find_element(By.ID, 'su').click()
sleep(3)          

常用操作

定位下拉菜单

注意
在定位下拉菜单时,要先定位到父级元素,然后再做一个模拟光标移动,再点击所选项
页面代码

<html><head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><title>Level Locate</title>    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script><link href="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.9/dist/css/bootstrap.min.css" rel="stylesheet" />    </head><body><h3>Level locate</h3><div class="span3 col-md-3">    <div class="well"><div class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Link1</a><ul class="dropdown-menu" role="menu" aria-labelledby="dLabel" id="dropdown1" ><li><a tabindex="-1" href="http://www.bjsxt.com">Action</a></li><li><a tabindex="-1" href="#">Another action</a></li><li><a tabindex="-1" href="#">Something else here</a></li><li class="divider"></li><li><a tabindex="-1" href="#">Separated link</a></li></ul></div>        </div>      </div><div class="span3 col-md-3">    <div class="well"><div class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Link2</a><ul class="dropdown-menu" role="menu" aria-labelledby="dLabel" ><li><a tabindex="-1" href="#">Action</a></li><li><a tabindex="-1" href="#">Another action</a></li><li><a tabindex="-1" href="#">Something else here</a></li><li class="divider"></li><li><a tabindex="-1" href="#">Separated link</a></li></ul></div>        </div>      </div></body><script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.9/dist/js/bootstrap.min.js"></script></html>

核心代码

# 定位父级元素
chrome.find_element(By.LINK_TEXT, 'Link1').click()
sleep(4)
# 做一个移动光标的动作【模拟人工,非必要】
menu = chrome.find_element(By.LINK_TEXT, 'Action')
webdriver.ActionChains(chrome).move_to_element(menu).perform()
# 定位子集元素
menu.click()



示例代码

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import By
import osservice = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
file_path = 'file:///' + os.path.abspath('./1.下拉菜单.html')
chrome.get(file_path)
sleep(3)
# 定位父级元素
chrome.find_element(By.LINK_TEXT, 'Link1').click()
sleep(4)
# 做一个移动光标的动作【模拟人工,非必要】
menu = chrome.find_element(By.LINK_TEXT, 'Action')
webdriver.ActionChains(chrome).move_to_element(menu).perform()
# 定位子集元素
menu.click()
sleep(4)            

定位下拉框

简介
相比定位下拉菜单,下拉框可以直接定位到元素
页面代码

<html>
<body>
<select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod"><option value="12.51">UPS Next Day Air ==> $12.51</option><option value="11.61">UPS Next Day Air Saver ==> $11.61</option><option value="10.69">UPS 3 Day Select ==> $10.69</option><option value="9.03">UPS 2nd Day Air ==> $9.03</option><option value="8.34">UPS Ground ==> $8.34</option><option value="9.25">USPS Priority Mail Insured ==> $9.25</option><option value="7.45">USPS Priority Mail ==> $7.45</option><option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>


核心代码

# 定位到选择框,并利用xpath进行选取
m = chrome.find_element(By.ID, "ShippingMethod")
m.find_element(By.XPATH, "//option[@value='10.69']").click()



示例代码
 

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import By
import osservice = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
file_path = 'file:///' + os.path.abspath('./3.drop_down.html')
chrome.get(file_path)
sleep(3)
# 定位到选择框,并利用xpath进行选取
m = chrome.find_element(By.ID, "ShippingMethod")
m.find_element(By.XPATH, "//option[@value='10.69']").click()
sleep(3)
chrome.quit()

定位层级内元素

简介
有时候我们定位一个元素,定位器没有问题,但一直定位不了,这时候就要检查这个元素是否在一个frame中
页面代码

<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><title>inner</title>
</head>
<body>
<div class="row-fluid"><div class="span6 well"><h3>inner</h3><iframe id="f2" src="https://cn.bing.com/" width="700" height="500"></iframe></div>
</div>
</body>
</html>
<html>
<head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><title>frame</title><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script><link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css"rel="stylesheet"/>
</head><body>
<div class="row-fluid"><div class="span10 well"><h3>frame</h3><iframe id="f1" src="2.inner.html" width="800" , height="600"></iframe></div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/@bootcss/v3.bootcss.com@1.0.8/dist/js/bootstrap.min.js"></script>
</html>
</html>


核心代码

可以利用以下方法进入到内层元素【参数时id属性】
chrome.switch_to.frame('f1')



示例代码

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import By
import os# 定位层级内元素【三层】
service = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
file_path = 'file:///' + os.path.abspath('./2.outer.html')
chrome.get(file_path)
sleep(3)
# 切换到frame里【根据id】
chrome.switch_to.frame('f1')
chrome.switch_to.frame('f2')
# 定位三层里的元素【www.baidu.com】
chrome.find_element(By.ID, 'sb_form_q').send_keys('CSDN')
chrome.find_element(By.ID, 'search_icon').click()
sleep(3)

处理弹窗

页面代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>This is a page</title>
</head>
<body>
<div id="container"><div style="font: size 30px;">Hello,Python Spider</div>
</div>
</body>
<script>alert('这个是测试弹窗')</script>
</html>

核心代码

# 定位弹出窗口,并点击
chrome.switch_to.alert.accept()



示例代码

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import By
import osservice = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
file_path = 'file:///' + os.path.abspath('./4.弹出框.html')
chrome.get(file_path)
sleep(3)
# 定位弹出窗口,并点击
chrome.switch_to.alert.accept()
sleep(4)
chrome.quit()

拖拽元素

简介
拖拽元素:如拖拽div标签【块级】

页面代码

<!doctype html>
<html lang="en">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>jQuery UI Draggable - Auto-scroll</title><link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"><style>#draggable, #draggable2, #draggable3 { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 0 10px 10px 0; }body {font-family: Arial, Helvetica, sans-serif;}table {font-size: 1em;}.ui-draggable, .ui-droppable {background-position: top;}</style><script src="https://code.jquery.com/jquery-1.12.4.js"></script><script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script><script>$( function() {$( "#draggable" ).draggable({ scroll: true });$( "#draggable2" ).draggable({ scroll: true, scrollSensitivity: 100 });$( "#draggable3" ).draggable({ scroll: true, scrollSpeed: 100 });} );</script>
</head>
<body>
<div id="draggable" class="ui-widget-content"><p>Scroll set to true, default settings</p>
</div><div id="draggable2" class="ui-widget-content"><p>scrollSensitivity set to 100</p>
</div><div id="draggable3" class="ui-widget-content"><p>scrollSpeed set to 100</p>
</div>
<div style="height: 5000px; width: 1px;"></div>
</body>
</html>



核心代码

# 定位要拖拽的元素
div1 = chrome.find_element(By.ID, 'draggable')
div2 = chrome.find_element(By.ID, 'draggable2')
div3 = chrome.find_element(By.ID, 'draggable3')
sleep(3)
# 拖拽【把div1拖拽到div2处】
ActionChains(chrome).drag_and_drop(div1, div2).perform()
sleep(3)
# 拖拽【把div3向左/下各拖拽10px】
ActionChains(chrome).drag_and_drop_by_offset(div3, 10, 10).perform()
sleep(3)



示例代码

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import By
import os# 定位弹出框
service = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
file_path = 'file:///' + os.path.abspath('./5.拖拽元素.html')
chrome.get(file_path)
sleep(3)
# 定位要拖拽的元素
div1 = chrome.find_element(By.ID, 'draggable')
div2 = chrome.find_element(By.ID, 'draggable2')
div3 = chrome.find_element(By.ID, 'draggable3')
sleep(3)
# 拖拽【把div1拖拽到div2处】
ActionChains(chrome).drag_and_drop(div1, div2).perform()
sleep(3)
# 拖拽【把div3向左/下各拖拽10px】
ActionChains(chrome).drag_and_drop_by_offset(div3, 10, 10).perform()
sleep(3)
chrome.quit()

调用JS方法

简介
有时候我们需要控制页面滚动条上的滚动条,但滚动条并非页面上的元素,这个时候就需要借助js是来进行操作

注意
js都可以直接打开浏览器开发者工具去测试
控制台————输入js即可

核心代码

js = "window.scrollTo(100,400)"# 拉动滚动条
driver.execute_script(js)



示例代码

from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from time import sleepservice = Service('./chromedriver.exe')
chrome = webdriver.Chrome(service=service)
chrome.get('https://www.jd.com/')
# 拉动滚动条
js = "window.scrollTo(100,400)"
chrome.execute_script(js)
sleep(3)            

功能

等待元素

强制等待
作用:当代码运行到强制等待这一行的时候,无论出于什么原因,都强制等待指定的时间,需要通过time模块实现
优点:简单
缺点:无法做有效的判断,会浪费时间

from time import sleep
sleep(3)



隐式等待
作用:到了一定的时间发现元素还没有加载,则继续等待我们指定的时间,
如果超过了我们指定的时间还没有加载就会抛出异常,如果没有需要等待的时候就已经加载完毕就会立即执行
优点: 设置一次即可,所有操作都会等待
缺点:必须等待加载完成才能到后续的操作,或者等待超时才能进入后续的操作

from selenium import webdriver
chrome.implicitly_wait(10)


显示等待
作用:指定一个等待条件,并且指定一个最长等待时间,会在这个时间内进行判断是否满足等待条件,如果成立就会立即返回,
如果不成立,就会一直等待,直到等待你指定的最长等待时间,如果还是不满足,就会抛出异常,如果满足了就会正常返回
优点:专门用于对指定一个元素等待,加载完即可运行后续代码
缺点:多个元素都需要要单独设置等待

from selenium.webdriver.support.wait import WebDriverWait
# 0.5:指定检查条件的频率,单位为秒。也就是每隔0.5秒检查一次条件是否满足
wait = WebDriverWait(driver,10,0.5)
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'next')))


        

隐藏浏览器

实现

# 设置参数,将浏览器隐藏起来(无头浏览器)
options = ChromeOptions()
options.add_argument('--headless')
# 创建Chrome浏览器时加入参数
service = Service('./chromedriver')
driver = Chrome(service=service,options=options)

代理模式

实现1

# 设置参数,给浏览器设置代理
options = ChromeOptions()
# options.add_argument('--proxy-server=http://ip:port')
options.add_argument('--proxy-server=http://221.199.36.122:35414')
# 设置驱动
service = Service('./chromedriver')
# 启动Chrome浏览器
driver = Chrome(service=service,options=options)



实现2

from selenium.webdriver.common.proxy import ProxyType,Proxy
# 设置参数,给浏览器设置代理
ip = 'http://113.76.133.238:35680'
proxy = Proxy()
proxy.proxy_type = ProxyType.MANUAL
proxy.http_proxy = ip
proxy.ssl_proxy = ip
# 关联浏览器
capabilities = DesiredCapabilities.CHROME
proxy.add_to_capabilities(capabilities)# 设置驱动
service = Service('./chromedriver')
# 启动Chrome浏览器
driver = Chrome(service=service,desired_capabilities=capabilities)

防检测设置

实现

from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptionsoptions = ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-automation'])
options.add_experimental_option('useAutomationExtension', False)chrome = Chrome(chrome_options=options)
chrome.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => false
})
"""
})chrome.get('http://httpbin.org/get')
info = chrome.page_sourceprint(info)
sleep(20)          

实战

虎牙

爬取英雄联盟全部分页的主播和对应的人气

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from lxml import etree
from selenium.webdriver.common.by import Byservice = Service('../0.工具/chromedriver.exe')
chrome = webdriver.Chrome(service=service)
# 设置隐式等待
chrome.implicitly_wait(5)
# 爬取英雄联盟页面的数据
chrome.get('https://www.huya.com/g/lol')
# 做一个循环,退出条件是下一页没有数据
while True:# 分析数据e = etree.HTML(chrome.page_source)names = e.xpath('//i[@class="nick"]/@title')  # 获取主播昵称person_nums = e.xpath('//i[@class="js-num"]/text()')  # 获取主播人气# 提取数据for n, p in zip(names, person_nums):print(f'{n}————————————{p}')try:# 找到下一页的按钮next_btn = chrome.find_element(By.XPATH, '//a[@class="laypage_next"]')# 点击下一页next_btn.click()except Exception as e:break# if chrome.page_source.find('laypage_next') == -1:#     break# # 找到下一页的按钮# next_btn = chrome.find_element(By.XPATH, '//a[@class="laypage_next"]')# # 点击下一页# next_btn.click()
chrome.quit()

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

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

相关文章

支付总架构解析

一、支付全局分层 一笔支付以用户为起点&#xff0c;经过众多支付参与者之后&#xff0c;到达央行的清算账户&#xff0c;完成最终的资金清算。那么我们研究支付宏观&#xff0c;可以站在央行清算账户位置&#xff0c;俯视整个支付金字塔&#xff0c;如图1所示&#xff1a; 图…

使用Openoffice或LibreOffice实现World、Excel、PPTX在线预览

使用Openoffice或LibreOffice实现World、Excel、PPTX在线预览 预览方案使用第三方服务使用前端库转换格式 jodconverterjodconverter概述主要特性OpenOfficeLibreOffice jodconverter的基本使用添加依赖配置创建DocumentConverter实例上传与转换预览启动上传与预览World 与Spri…

01:STM32点灯大师和蜂鸣器

目录 一:点亮1个LED 1:连接图 2:函数介绍 3:点灯代码 二:LED闪烁 1:函数介绍 2:闪烁代码 三:LED流水灯 1:连接图 2:函数介绍 3:流水灯代码 四:蜂鸣器 1:连接图 2:蜂鸣器代码 一:点亮1个LED 1:连接图 因为IO口与LED负极相连所以IO口输出低电频,点亮LED (采用的是低…

构建Docker容器监控系统 (1)(Cadvisor +InfluxDB+Grafana)

目录 Cadvisor InfluxDBGrafana 1. Cadvisor 2.InfluxDB 3.Grafana 开始部署&#xff1a; 下载组件镜像 创建自定义网络 创建influxdb容器 创建数据库和数据库用户 创建Cadvisor 容器 准备测试镜像 创建granafa容器 访问granfana 添加数据源 Add data source 新建 …

存储过程的学习

1&#xff0c;前言 这是实习期间学习的&#xff0c;我可能是在学校没好好听课&#xff0c;&#xff08;或者就是学校比较垃&#xff0c;没教这部分&#xff0c;在公司经理让我下去自己学习&#xff0c;太难了&#xff0c;因为是公司代码很多部分都是很多表的操作&#…

Flutter:文件上传与下载(下载后预览)

Dio dio是一个强大的Dart Http请求库&#xff0c;提供了丰富的功能和易于使用的API&#xff0c;支持文件上传和下载。 这个就不介绍了&#xff0c;网上有很多的封装案例。 background_downloader 简介 适用于iOS&#xff0c;Android&#xff0c;MacOS&#xff0c;Windows和L…

开发者须知,App和小程序须备案,否则面临清退!

备案并不陌生&#xff0c;前端开发的老铁肯定熟悉&#xff0c;若你的网站未备案情况下&#xff0c;在国内的服务器是无法访问的&#xff0c;所谓备案&#xff0c;通常指的就是ICP备案&#xff0c;需要把你经营的信息&#xff0c;给相关部门进行报备&#xff0c;简而言之&#x…

[每周一更]-(第58期):选购佳能变焦镜头 EF-S 18-200mm F/3.5-5.6 IS的心得

参考地址&#xff1a; https://www.canon.com.cn/purchase/onlinesale/index3.html?typejdhttps://www.canon.com.cn/overview/efwidezoom.html 讲在买之前 由于没有买全画幅&#xff0c;买了残幅&#xff0c;好处是能选的镜头有限&#xff0c;不用太费钱了&#xff0c;需要…

element-plus:el-date-picker日期只选择年月不要日

<el-date-picker v-model"value" type"month" format"YYYY-MM" value-format"YYYY-MM" />使用format属性将时间显示格式修改为YYYY–MM 年月格式 使用value-format将绑定值的格式修改为YYYY–MM年月格式

如何快速解决集成环信IM遇到的问题?

1、环信FAQ频道发布了 环信FAQ帮助中心提供了各客户端、RESTful API、环信控制台以及商务相关的集成环信常见问题及解决方法&#xff0c;帮您快速解决集成问题 2、当我有问题时&#xff0c;从哪里进FAQ&#xff1f; 干脆收藏这个网址&#xff1a;https://faq.easemob.com/ 环…

ASL国产CS5212规格书 DP转VGA 替代RTD2166低成本方案 兼容IT6516设计原理图

CS5212可替代兼容瑞昱RTD2166和联阳T6516&#xff0c;ASL集睿致远这款芯片是一种高性能的DP显示端口到VGA转换器芯片。它结合了DisplayPort输入接口和模拟RGB DAC输出接口&#xff0c;嵌入式单片机基于工业标准8051核心。 CS5212适用于多个细分市场和显示器应用程序&#xff1…

Java 包装类(Wrapper)

Wrapper概念 Java是一个面向对象的编程语言&#xff0c;但是Java中的八种基本数据类型却是不面向对象的&#xff0c;为了使用方便和解决这个不足&#xff0c;在设计类时为每个基本数据类型设计了一个对应的类进行代表&#xff0c;这样八种基本数据类型对应的类统称为包装类(Wra…