一、什么是Selenium

Selenium 是一个用于 Web 应用程序测试的工具。Selenium 测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括Mozilla Firefox,Safari,Chrome,Opera,Edge 等

二、Selenium 优势

1、免费开源

2、小巧,对于不同的语言而言,只是一个包的大小

3、支持多语言,python,java 等

4、支持多平台,多浏览器

三、Selenium 原理

上图所示Selenium Client Library就是我们平时使用的编码语言,包括 java、python、C#等。可以看到这些语言并没有直接与 Browser Drivers 进行通信,而是通过了 JSON WireProtocol,这就是 webdriver 协议。

简单的说他定义了一套接口规范,以我们最熟悉的点击操作为例,他对应的接口协议是:

POST /session/{session id}/element/{element id}/click

这样以来,无论我们编码使用 python 代码来执行点击操作:

driver.find_element_by_id(“”).click()

还是以 java 代码执行点击操作:

driver.findElement(By.id(“”)).click();

都会通过 selenium 客户端的程序将 click 操作转化成对应的 webdriver 协议。这样对于 Browser Drivers 来说只需要解析具体协议,而无需关注客户端使用的是哪种代码了,这就是 selenium 支持多种语言的原理。

在 Browser Drivers 中可以看到各个浏览器的 driver,这里我们以 chromedriver 为例进行讲解。在代码中直接 new ChromeDriver() 将会启动一个 ChromeDriver 进程,ChromeDriver 是一个独立的服务,它是 google 为网站开发人员提供的自动化测试接口,它是 selenium 和 chrome 浏览器进行通信的桥梁。chromeDriver 解析 webdriver 协议,然后根据解析结果,调用与之对应的 Remote Debugging 协议来操控 chrome 浏览器,它可以和浏览器内核进行交互进而操控浏览器

四、浏览器驱动

当 selenium 升级到 3.0 之后,对不同的浏览器驱动进行了规范。如果想使用 selenium 驱动不同的浏览器,必须单独下载并设置不同的浏览器驱动。

各浏览器驱动下载地址:

Firefox 浏览器驱动:geckodriver

Chrome 浏览器驱动:chromedriver , taobao镜像

Edge 浏览器驱动:MicrosoftWebDriver

Opera 浏览器驱动:operadriver

五、python 安装Selenium

通过命令安装:pip install selenium

注:如果电脑上既有 python2,又有 python3,在执行 pip 命令安装时,要注意区分

六、设置浏览器驱动

1、设置浏览器的地址非常简单。 我们可以手动创建一个存放浏览器驱动的目录,如: C:\driver ,将下载的浏览器驱动文件放到该目录下,然后将此目录路径放在环境变量 Path 下

2、python 验证不同的浏览器驱动是否正常使用

from selenium import webdriver
 
driver = webdriver.Firefox()   # Firefox浏览器

driver = webdriver.Chrome()    # Chrome浏览器
 
driver = webdriver.Edge()      # Edge浏览器
 
driver = webdriver.Opera()     # Opera浏览器

3、测试是否正常打开浏览器

from selenium import webdriver
 
driver = webdriver.Chrome()
driver.get('https://www.baidu.com') # 打开百度
 
print(driver.title) # 获取网页title
 
driver.quit() # 关闭浏览器

七、常用功能

1、元素定位

常用元素定位为 8 种,分别为:

通过 id 定位:find_element_by_id()

通过 id 定位一组元素:find_elements_by_id()

通过 name 定位:find_element_by_name()

通过 name 定位一组元素:find_elements_by_name()

通过 class name 定位:find_element_by_class_name()

通过 class name 定位一组元素:find_elements_by_class_name()

通过 tag name 定位:find_element_by_tag_name()

通过 tag name 定位一组元素:find_elements_by_tag_name()

通过 link text 定位:find_element_by_link_text()

通过 link text 定位一组元素:find_elements_by_link_text()

通过部分 link text 定位:find_element_by_partial_link_text()

通过部分 link text 定位一组元素:find_elements_by_partial_link_text()

通过 xpath 定位:find_element_by_xpath()

通过 xpath 定位一组元素:find_elements_by_xpath()

通过 css 定位:find_element_by_css_selector()

通过 css 定位一组元素:find_elements_by_css_selector()

注意:如果定位一组元素,则在 element 后面加一个 s

2、控制浏览器

  • 控制浏览器大小
from selenium import webdriver

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
 
# 参数数字为像素点
print("设置浏览器宽500、高500显示")
driver.set_window_size(500, 500)
driver.quit()
  • 控制浏览器前进后退
from selenium import webdriver
 
driver = webdriver.Firefox()
 
#访问百度首页
first_url= 'http://www.baidu.com'
print("access %s" %(first_url))
driver.get(first_url)
 
#访问新闻页面
second_url='http://news.baidu.com'
print("access %s" %(second_url))
driver.get(second_url)
 
#返回(后退)到百度首页
print("back to  %s "%(first_url))
driver.back()
 
#前进到新闻页
print("forward to  %s"%(second_url))
driver.forward()
 
driver.quit()

3、WebDriver 常用方法

  • clear(): 清除文本
  • send_keys (value): 模拟按键输入
  • click(): 单击元素
from selenium import webdriver
 
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
driver.quit()
  • submit():用于提交表单
from selenium import webdriver
 
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
 
search_text = driver.find_element_by_id('kw')
search_text.send_keys('selenium')
search_text.submit()
 
driver.quit()

4、设置元素等待

WebDriver 提供了两种类型的等待:显式等待和隐式等待

显式等待使 WebdDriver 等待某个条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
 
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
 
element = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, "kw")))
element.send_keys('selenium')
driver.quit()

隐式等待并不影响脚本的执行速度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则它将以轮询的方式不断地判断元素是否被定位到。假设在第 5 秒定位到了元素则继续执行,若直到超出设置时长(10 秒)还没有定位到元素,则抛出异常。

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from time import ctime
 
driver = webdriver.Chrome()
 
# 设置隐式等待为10秒
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
 
try:
    print(ctime())
    driver.find_element_by_id("kww").send_keys('selenium')
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

八、Python+Selenium 实现识别图片验证码登录

1、打开网站设置要访问的网站地址,并把窗口最大化,这是能保证在电脑上每次截取的图片都是相同的大小

url = "https://www.xxxxx.com"
# 1、打开浏览器,最大化浏览器
driver = webdriver.Chrome()
driver.get(url)
#driver.implicitly_wait(10)#隐式等待10s
driver.maximize_window()#最大化窗口

2、截取带图片验证码的网站内容,并保存在本地

driver.save_screenshot("H://test/01.png")#截取屏幕内容,保存到本地

也可以通过 id 或者 Xpath 的方式定位到图片验证码的方式直接获取图片验证码,保存在本地

3、使用第三方库对图片进行识别(pytesseract 和ddddocr 都可以识别图片验证码)

a、使用pytesseract 识别图片验证码

定位在图片中验证码所在的位置,四个参数分别代表图片验证码的左,上,右,下坐标,可以通过 windows 自带的画图工具获取

当使用通过定位获取到验证码的方式时,可以跳过手动获取图片验证码的流程,直接跳转到图像处理步骤

ran = Image.open("H://test/01.png")#打开截图,获取验证码位置,截取保存验证码
box = (564, 395, 643, 423)  # 获取验证码位置,代表(左,上,右,下)
ran.crop(box).save("H://test/02.png")#把获取的验证码保存
#获取验证码图片,读取验证码
imageCode = Image.open("H://test/02.png")  #打开保存的验证码图片
#imageCode.load()
# 图像增强,二值化
sharp_img = ImageEnhance.Contrast(imageCode).enhance(2.0)
sharp_img.save("H://test/03.png")#保存图像增强,二值化之后的验证码图片
sharp_img.load()  # 对比度增强
time.sleep(2)
print(sharp_img)#打印图片的信息
code = pytesseract.image_to_string(sharp_img).strip()#读取验证码

b、使用 ddddocr 识别图片验证码

先将图片保存在本地,然后可以直接通过二进制读取图片,进行识别

# 创建对象
ocr = ddddocr.DdddOcr() 
# 使用二进制的方式读取图片
with open('./images/code1.png', 'rb') as f:
    img_tytes = f.read()
    # 调用识别方法
    res = ocr.classification(img_tytes)
    print(f'验证码为:{res}')

4、定位账号密码等输入框,并输入相关内容

name=driver.find_element_by_id("username")#定位账号输入框
password=driver.find_element_by_id("password_1")#定位密码输入框
code1=driver.find_element_by_id("user_ck")#定位验证码输入框
name.send_keys('username')#给定位账号的输入框中输入值
password.send_keys('password')#给定位密码的输入框中输入值
code1.send_keys(code)#给定位验证码的输入框中输入读取到的验证码

5、定位并点击按钮

driver.find_element_by_name("yt0").click()#点击登录

6、最后关闭页面

#关闭浏览器
driver.quit()

九、问题和解决方案

在使用pytesseract图片识别过程中,会报错 tesseract-ocr 相关信息

这个时候,可以通过https://github.com/UB-Mannheim/tesseract/wiki中下载 tesseract-ocr

打开 pytesseract.py 文件,找到 tesseract_cmd,将原来的注释掉,然后添加新的:tesseract_cmd=”新下载的tesseract-ocr 保存路径/tesseract.exe”,即可解决此问题

参考文献

Ravinder Singh. Selenium WebDriver Achitecture[EB/OL]. 2021 年 11 月 22 日[2022 年 7 月 20 日]. https://www.toolsqa.com/selenium-webdriver/selenium-webdriver-architecture/.

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注