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

常用操作

定位下拉菜单

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

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

定位下拉框

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

<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 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中
页面代码

<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 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标签【块级】

页面代码

<!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 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模块实现
优点:简单
缺点:无法做有效的判断,会浪费时间

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

实战

虎牙

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

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

        

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月木@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值