一、环境搭建

1、selenium环境搭建

Client:

  •  pycharm
  •  python3.6

Driver:

  •  Chrome → ChromeDriver
  •  Firefox  → FirefoxDriver
  •  IE         → InternetExplorerDriver

Selenium


 

1.1、Selenium安装

pip install selenium  # 安装
from selenium import webdriver # 导入
driver = webdriver.Chrome() # 启动谷歌浏览器
driver.get("http://www.baidu.com") # 打开百度网址
# 注意:启动谷歌浏览器前需要配置好谷歌浏览器中间件 ,从网上下载chromedriver.exe ,将其放置到python的安装目录下

1.2、使用脚本启动不同浏览器

启动浏览器前需配置好浏览器对应driver:

  • Chrome --chromedriver.exe :谷歌浏览器调试驱动插件
  • Firefox --geckodrive.exe : 火狐浏览器调试驱动插件
  • IE --MicrosoftWebDriver.exe : IE浏览器调试驱动插件

将上面三个exe文件下载后放置到python目录下

1)启动谷歌浏览器

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')

 

2)启动火狐浏览器:

from selenium import webdriver

driver = webdriver.Firefox()
driver.get('http://www.baidu.com')

 

3)启动IE浏览器

from selenium import webdriver

driver = webdriver.Ie()
# driver = webdriver.Edge()  # win 10版本启动IE浏览器,使用此行代码
driver.get('http://www.baidu.com')

 

2、使用expected_condition下的 title_contains判断页面标题是否与我们想要的一致,如判断页面标题是否有‘注册’字眼:

from selenium import webdriver
from selenium.webdriver.support import expected_conditions
import time

driver = webdriver.Chrome()
# driver = webdriver.Edge()  # win 10版本启动IE浏览器,使用此行代码
driver.get('http://www.5itest.cn/register')
time.sleep(5)
is_live = expected_conditions.title_contains('注册')  # 判断页面的标题中是否有注册两字
print('is_live:',is_live)

 

返回结果:

is_live: <selenium.webdriver.support.expected_conditions.title_contains object at 0x000000000354DEF0>  # 存在

 

3、使用不同方式进行定位

访问注册链接:http://www.5itest.cn/register ,进行测试

 Selenium3与Python3实战 Web自动化测试框架(一)

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.5itest.cn/register')
driver.find_element_by_id('register_email').send_keys("nan@163.com")  # 填写邮箱
user_name_node = driver.find_elements_by_class_name('controls')[1]  # 使用classname进行定义,需要细心处理
user_name_node.find_element_by_class_name('form-control').send_keys('Eric_nan')  # 填写用户名
driver.find_element_by_name('password').send_keys('111111')  # 填写密码
driver.find_element_by_xpath('//*[@> 填写验证码

 

脚本控制启动浏览器并访问注册页面,同时自动输入我们设定的值:

 Selenium3与Python3实战 Web自动化测试框架(一)


 

4、使用expected_conditions判断元素是否可见

from selenium import webdriver
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

locator = (By.CLASS_NAME,'controls')  # 通过classname的方式 找到 controls
WebDriverWait(driver,1).until(expected_conditions.visibility_of_element_located(locator))
# WebDriverWait: 传入两个参数,一个是driver,另一个是超时时间(int类型)
# visibility_of_element_located:只在可见的元素里找对应的元素。如有返回内存地址

 

 5、如何解决验证码自动输入

 1)将注册页面全屏截图保存(使用driver.save_screenhot方法),再将验证码部分区域截图保存下来

打开本地图片、截取部分区域需要用到PIL ,安装:pip install -i https://pypi.douban.com/simple Pillow

driver = webdriver.Chrome()

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 项目首路径
image_path = os.path.join(base_dir,'Image','imooc.png')  # 图片路径,用于保存全屏截图后的图片
code_path = os.path.join(base_dir,'Image','code.png')  # 验证码图片保存路径

driver.get('http://www.5itest.cn/register')
driver.save_screenshot(image_path)  # 全屏截图
code_element = driver.find_element_by_id("getcode_num") # 定位到验证码所在的文字
# print(code_element.location)   # 获取该元素(图片)左上角的(x,y)坐标
# print(code_element.size)   # 获取该元素(图片)长度、宽度
left_x = code_element.location['x'] # 左上角x值
top_y = code_element.location['y'] # 左上角y值
right_x = left_x + code_element.size['width']  # 右下角x值
right_y = top_y + code_element.size['height']  # 右下角y值

im = Image.open(image_path) # 使用PIL下的Image打开下载的imooc.png图片
img = im.crop((left_x,top_y,right_x,right_y))  # 将指定的某部分裁剪出来
img.save(code_path) # 保存

 

 2)使用 showapiRequest解决图片验证码识别

 ①、使用pytesseract识别图片中得问题

  安装:pip install pytesseract

import pytesseract
from PIL import Image

image = Image.open("E:/imooc2.png")
text = pytesseract.image_to_string(image) # 将图片文字转换成字符串
print(text)

# 缺点:机械性读取,无法读取图片中不规则的字体,不适合于干扰性比较强的验证码图片文字读取

 

②、 使用 showapiRequest解决图片验证码识别(需收费,每测试识别一次都会收取费用,低至0.01)

 进入万维易源网:https://www.showapi.com/api/view/184/4

 选择:验证码识别英数_文件 ,找到请求示例,下载SDK:ShowapiRequest.py

 Selenium3与Python3实战 Web自动化测试框架(一)

将 ShowapiRequest.py文件放到项目中,新建read_code_img.py文件,用于读取图片中的验证码:

 验证码:Selenium3与Python3实战 Web自动化测试框架(一)

from setting.ShowapiRequest import ShowapiRequest
from setting import setting


r = ShowapiRequest("http://route.showapi.com/184-4","62666","d61950be50dfgjnr9969f741b8e730f5" )
# ShowapiRequest 的第一个参数是万维易源网的url ,第二个参数是易源网上你个人的appId , 第三个参数是易源网上的密钥
r.addBodyPara("typeId", "35") #typeId:表示识别几位数的图片验证码 ;35:'3'表示英数结合的验证码,'5'表示5位数的验证码 ; 31:一位数的验证码 r.addBodyPara("convert_to_jpg", "0") r.addFilePara("image", setting.code_path) # 添加要识别验证码的图片 res = r.post() print(res.text) # {"showapi_res_error":"","showapi_res_id":"6f0e4cdb977141b293ea12178ad3d37e","showapi_res_code":0,"showapi_res_body":{"Id":"5bac83cc-5637-4e2d-bc91-25a78b527241","Result":"ANLZZ","ret_code":0}} text = res.json()['showapi_res_body']['Result']# 以json格式读取:showapi_res_body 下 Result 的值 print(text) # 返回信息:ANLZZ (识别正确)

 注:这种方式识别准确率比较高


 

 将注册相关代码封装起来-初次封装

from selenium import webdriver
from setting.ShowapiRequest import ShowapiRequest
from setting import setting
from PIL import Image

import time
import random

class Register_Operate(object):
    def __init__(self,file_name):
        # 浏览器初始化
        self.driver = webdriver.Chrome()
        self.driver.get('http://www.5itest.cn/register')
        self.driver.maximize_window() # 窗口最大化
        self.file_name = file_name

    def get_element(self,id):
        # 获取element信息
        element = self.driver.find_element_by_id(id)
        return element

    def get_range_for_user(self):
        # 获取随机字符串,用于邮箱随机输入、用户名随机输入
        user_info = ''.join(random.sample('1234567890abcdefghijklmn',9))
        return user_info


    def get_code_image(self):
        # 获取验证码图片,并保存到file_name中
        self.driver.save_screenshot(self.file_name)  # 全屏截图,保存到file_name
        code_element = self.get_element("getcode_num")  # 定位到验证码所在的文字
        # print(code_element.location)   # 获取该元素(图片)左上角的(x,y)坐标
        # print(code_element.size)   # 获取该元素(图片)长度、宽度
        left_x = code_element.location['x']  # 左上角x值
        top_y = code_element.location['y']  # 左上角y值
        right_x = left_x + code_element.size['width']  # 右下角x值
        right_y = top_y + code_element.size['height']  # 右下角y值

        im = Image.open(self.file_name)  # 使用PIL下的Image打开下载的imooc.png图片
        img = im.crop((left_x, top_y, right_x, right_y))  # 将指定的某部分裁剪出来(验证码图片)
        img.save(self.file_name)  # 保存到file_name中


    def code_online(self):
        # 将file_name中的验证码图片进行识别,用于注册时验证码输入
        r = ShowapiRequest("http://route.showapi.com/184-4", "62626", "d61950be50dc4dbd9969f741b8e730f5")
        r.addBodyPara("typeId", "35")  # typeId:表示识别几位数的图片验证码 ;35:'3'表示英数结合的验证码,'5'表示5位数的验证码   ; 31:一位数的验证码
        r.addBodyPara("convert_to_jpg", "0")
        r.addFilePara("image", self.file_name)  # 添加要识别验证码的图片,image:图片格式,setting.code_path:图片位置
        res = r.post()
        # print(res.text)  # {"showapi_res_error":"","showapi_res_id":"6f0e4cdb977141b293ea12178ad3d37e","showapi_res_code":0,"showapi_res_body":{"Id":"5bac83cc-5637-4e2d-bc91-25a78b527241","Result":"ANLZZ","ret_code":0}}
        code_text = res.json()['showapi_res_body']['Result']  # 以json格式读取:showapi_res_body 下 Result 的值
        # print(code_text)
        return code_text

    def run_main(self):
        # 主程序
        user_name = self.get_range_for_user()  # 用户名
        user_email = user_name + '@163.com'  # 邮箱
        self.get_element("register_email").send_keys(user_email)  # 定位邮箱,并自动输入随机获取的邮箱号
        self.get_element("register_nickname").send_keys(user_name)  # 自动输入用户名
        self.get_element("register_password").send_keys("111111")  # 自动输入密码
        self.get_code_image()  # 获取验证码图片,保存于服务器
        code_text = self.code_online() # 识别验证码图片,获取验证码
        print(code_text)
        self.get_element("captcha_code").send_keys(code_text)  # 自动输入验证码
        self.get_element("register-btn").click()  # 注册按钮
        self.driver.close()   # 关闭浏览器
        time.sleep(3)
        self.driver.close()


if __name__ == "__main__":
    file_name = setting.code_path
    register_oper = Register_Operate(file_name)  # 实例化
    # time.sleep(1)
    register_oper.run_main()  # 运行主程序
注册自动输入对应信息

相关文章: