简介
就在前几天,有个朋友一直吐槽工作的时候需要通过不同的账号下载文件,一直问我能不能帮忙写一个简单的自动化工具实现,刚好端午节假期的到来就索性研究了下Python + Selenium。这也就是本次博客的内容了。
实现细节
- 创建项目
本次使用 Pycharm CE
开发工具进行,创建项目选择相对应的Python版本。
新建 Package
并创建 login.py
文件,其中 __init___.py
属于自生成文件可以不需要关注
- 引入库
打开File
进入 New Projects Settings Preferences | Python Interpreter
点击+ 号下载 本次所需要使用到的库:selenium
、PIL
、pytesseract
、cv2
- 编写业务代码
在 login.py
文件中将上方所下载的库在文件头中进行引入
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from PIL import Image
import pytesseract
import cv2 as cv
复制代码
在创建mian
函数并定义接下来所需要使用的参数,基于Selenium
必须指定对应浏览器驱动。
点我去下载驱动=
if __name__ == "__main__":
chromedriver_path = "/Users/mac/Source code/py/pythonProject/venv/lib/python3.8/site-packages/selenium/webdriver/chromedriver" #改成你的chromedriver的完整路径地址
# 定义你的账号/密码
username = "改成你的用户名" #用户名
password = "改成你的密码" #密码
复制代码
创建一个名为investorservice_info
的类并进行初始化webdriver
以及参数
class investorservice_info:
def __init__(self):
# 提前定义url 进行以便在login 函数中进行使用
url = 'https://investorservice.cfmmc.com/'
self.url = url
options = webdriver.ChromeOptions()
# options.add_experimental_option("prefs", {"profile.managed_default_content_settings.images": 2}) # 不加载图片,加快访问速度
options.add_experimental_option('excludeSwitches', ['enable-automation']) # 此步骤很重要,设置为开发者模式,防止被各大网站识别出来使用了Selenium
self.browser = webdriver.Chrome(executable_path=chromedriver_path, options=options)
self.browser.set_window_size(1024, 768) # 分辨率 1024*768
self.wait = WebDriverWait(self.browser, 10) #超时时长为10s
复制代码
创建一个login
函数,指定其需要打开的url,需要抓取的html
节点传入我们需要填写的用户、密码等内容
# 登录
def login(self):
# 打开网页
self.browser.get(self.url)
# 清空输入框并填入账号密码
self.browser.find_element_by_name('userID').clear()
self.browser.find_element_by_name('userID').send_keys(username)
self.browser.find_element_by_name('password').clear()
self.browser.find_element_by_name('password').send_keys(password)
复制代码
那么上方所指定的element
我们该如何进行抓取呢?,其实通过chrome
打开右上角更多按钮->更多工具->开发工具
找到节点,例如上方代码中的 userID
已知是name
通过find_element_by_name
即可定位节点,并你所需要设置的账号以及密码。
设置完账号密码,那么接下来就是验证码了。由于验证码是一张图片并且需要使用图像识别技术。这里简单的使用
cv2
以及 pytesseract
进行识别。首先定义一个recognize_text
函数,设置识别图片的灰度等各项参数
# 图像识别
def recognize_text(self,image):
# 边缘保留滤波 去噪
blur = cv.pyrMeanShiftFiltering(image, sp=8, sr=60)
cv.imshow('dst', blur)
# 灰度图像
gray = cv.cvtColor(blur, cv.COLOR_RGB2GRAY)
# 二值化 设置阈值 自适应阈值的话 黄色的4会提取不出来
ret, binary = cv.threshold(gray, 185, 255, cv.THRESH_BINARY_INV)
print(f'二值化设置的阈值:{ret}')
cv.imshow('binary', binary)
# 逻辑运算 让背景为白色 字体为黑 便于识别
cv.bitwise_not(binary, binary)
cv.imshow('bg_image', binary)
# 识别
test_message = Image.fromarray(binary)
test_message.save('new.png')
text = pytesseract.image_to_string(test_message)
print(f'识别结果:{text}')
return text
复制代码
将当前节点进行单独截图,并保存至项目根目录,通过cv
进行读取截图调用recognize_text
函数进行解析。
PS:CV指的是OpenCV
code = self.browser.find_element_by_id("imgVeriCode")
code.screenshot('imgVeriCode.png') # 针对当前节点进行单独截图
src = cv.imread('/Users/mac/Source code/py/pythonProject/imgVeriCode.png')
cv.imshow('input image', src)
vericode = self.recognize_text(src) #获取验证码文字
# 清空输入框并填入验证码
self.browser.find_element_by_name('vericode').clear()
self.browser.find_element_by_name('vericode').send_keys(vericode)
复制代码
通过以上几个步骤就把用户名、密码、验证码都已填入,下一步定位节点并模拟点击并进行登录了。
# 找到点击按钮节点,并点击按钮。
self.browser.find_element_by_class_name('buttonLogin').click()
复制代码
- 验证并进行测试
结语
- 本次通过OpenCv进行识别的验证码准确率非常低
- 本次使用的Selenium是一个自动化测试框架,API可自行查阅
- 本次实现的只是简单的登录并无特别的技术难点,期待下回的完整验证码解析以及文件下载
- 最后本次使用的网站只是做个 Demo 并无任何含义