探索自动化网页交互的魔力:学习 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)

打开页面

python 复制代码
chrome.get('http://www.baidu.com')

打开本地页面

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

获取页面html源码【换行】

python 复制代码
page = chrome.page_source

休眠

python 复制代码
from time import sleep
sleep(8)

关闭浏览器

python 复制代码
chrome.quit()

操作浏览器

窗口大小

python 复制代码
chrome.maximize_window() #窗口最大化
chrome.set_window_size(600, 800) #设置窗口大小

前进和后退

python 复制代码
chrome.forward()
chrome.back()

基础定位

定位元素

python 复制代码
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 清除对象的内容,如果可以的话

基础示例

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from time import sleep
from selenium.webdriver.common.by import By

service = 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)          

常用操作

定位下拉菜单

注意

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

页面代码

python 复制代码
<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>

核心代码

python 复制代码
# 定位父级元素
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()

示例代码

python 复制代码
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('./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)            

定位下拉框

简介

相比定位下拉菜单,下拉框可以直接定位到元素

页面代码

python 复制代码
<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>

核心代码

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

示例代码

python 复制代码
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('./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中

页面代码

python 复制代码
<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>
python 复制代码
<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>

核心代码

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

示例代码

python 复制代码
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)

处理弹窗

页面代码

python 复制代码
<!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>

核心代码

python 复制代码
# 定位弹出窗口,并点击
chrome.switch_to.alert.accept()

示例代码

python 复制代码
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('./4.弹出框.html')
chrome.get(file_path)
sleep(3)
# 定位弹出窗口,并点击
chrome.switch_to.alert.accept()
sleep(4)
chrome.quit()

拖拽元素

简介

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

页面代码

python 复制代码
<!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>

核心代码

python 复制代码
# 定位要拖拽的元素
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)

示例代码

python 复制代码
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即可

核心代码

python 复制代码
js = "window.scrollTo(100,400)"# 拉动滚动条
driver.execute_script(js)

示例代码

python 复制代码
from selenium.webdriver.chrome.service import Service
from selenium import webdriver
from time import sleep

service = 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模块实现

优点:简单

缺点:无法做有效的判断,会浪费时间

python 复制代码
from time import sleep
sleep(3)

隐式等待

作用:到了一定的时间发现元素还没有加载,则继续等待我们指定的时间,

如果超过了我们指定的时间还没有加载就会抛出异常,如果没有需要等待的时候就已经加载完毕就会立即执行

优点: 设置一次即可,所有操作都会等待

缺点:必须等待加载完成才能到后续的操作,或者等待超时才能进入后续的操作

python 复制代码
from selenium import webdriver
chrome.implicitly_wait(10)

显示等待

作用:指定一个等待条件,并且指定一个最长等待时间,会在这个时间内进行判断是否满足等待条件,如果成立就会立即返回,

如果不成立,就会一直等待,直到等待你指定的最长等待时间,如果还是不满足,就会抛出异常,如果满足了就会正常返回

优点:专门用于对指定一个元素等待,加载完即可运行后续代码

缺点:多个元素都需要要单独设置等待

python 复制代码
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')))

隐藏浏览器

实现

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

代理模式

实现1

python 复制代码
# 设置参数,给浏览器设置代理
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

python 复制代码
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)

防检测设置

实现

python 复制代码
from selenium.webdriver import Chrome
from selenium.webdriver import ChromeOptions

options = 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_source


print(info)
sleep(20)          

实战

虎牙

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

python 复制代码
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from lxml import etree
from selenium.webdriver.common.by import By

service = 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()

        
相关推荐
databook3 小时前
Manim实现闪光轨迹特效
后端·python·动效
Juchecar4 小时前
解惑:NumPy 中 ndarray.ndim 到底是什么?
python
用户8356290780514 小时前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_4 小时前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
数据智能老司机11 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机12 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i12 小时前
drf初步梳理
python·django
每日AI新事件12 小时前
python的异步函数
python