思路:使用谷歌浏览器chrome自动登录网页,把页面截图,再定位验证码,然后使用百度文字识别获取验证码实现登录
下载chromedriver.exe并放到项目目录下,选择自己谷歌浏览对应的版本 sites.google.com/a/chromium.…
1、使用之前必须要先安装第三方扩展库
pip install selenium
pip install Image
pip install baidu-aip
pip install pyinstaller # 安装pyinstaller,打包exe文件需要用到
2、封装百度云接口为baidu.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from aip import AipOcr
from aip import AipImageClassify
'''
百度云:https://console.bce.baidu.com/
接口说明:http://ai.baidu.com/ai-doc/OCR/3k3h7yeqa
'''
APP_ID = '百度云获取'
API_KEY = '百度云获取'
SECRET_KEY = '百度云获取'
# 文字识别
class word:
# {'log_id': 4411569300744191453, 'words_result_num': 1, 'words_result': [{'words': ' Y7Y.: 4'}]}
def __init__(self, filePath='', options='', url='', idCardSide='front'):
self.client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
# 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,
# 最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效
self.url = url
# 本地图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式
self.image = ''
# 可选参数
self.options = options
# front:身份证含照片的一面;back:身份证带国徽的一面
self.idCardSide = idCardSide
if filePath:
# 读取图片
with open(filePath, 'rb') as fp:
self.image = fp.read()
def General(self):
""" 调用通用文字识别, 50000次/天免费 """
return self.client.basicGeneral(self.image, self.options) # 还可以使用身份证驾驶证模板,直接得到字典对应所需字段
def GeneralUrl(self):
""" 调用通用文字识别, 图片参数为远程url图片 500次/天免费 """
return self.client.basicGeneralUrl(self.url, self.options)
def GeneralLocation(self):
""" 调用通用文字识别(含位置信息版), 图片参数为本地图片 500次/天免费 """
return self.client.general(self.url, self.options)
def GeneralUrlLocation(self):
""" 调用通用文字识别, 图片参数为远程url图片 500次/天免费 """
return self.client.generalUrl(self.url, self.options)
def Accurate(self):
""" 调用通用文字识别(高精度版) 500次/天免费 """
return self.client.basicAccurate(self.image, self.options)
def AccurateLocation(self):
""" 调用通用文字识别(含位置高精度版) 50次/天免费 """
return self.client.accurate(self.image, self.options)
def EnhancedGeneral(self):
""" 调用通用文字识别(含生僻字版), 图片参数为本地图片 """
return self.client.enhancedGeneral(self.image, self.options)
def EnhancedGeneralUrl(self):
""" 调用通用文字识别(含生僻字版), 图片参数为远程url图片 """
return self.client.enhancedGeneralUrl(self.image, self.options)
def Idcard(self):
""" 调用身份证识别, 图片参数为本地图片 front:身份证含照片的一面;back:身份证带国徽的一面 """
return self.client.idcard(self.image, self.idCardSide, self.options)
def Bankcard(self):
""" 调用银行卡识别 """
return self.client.bankcard(self.image)
def DrivingLicense(self):
""" 调用驾驶证识别 """
return self.client.drivingLicense(self.image, self.options)
def VehicleLicense(self):
""" 调用行驶证识别 """
return self.client.vehicleLicense(self.image, self.options)
def LicensePlate(self):
""" 调用车牌识别 """
return self.client.licensePlate(self.image, self.options)
def BusinessLicense(self):
""" 调用营业执照识别 """
return self.client.businessLicense(self.image, self.options)
def Receipt(self):
""" 调用通用票据识别 """
return self.client.idcard(self.image, self.options)
# 图像识别
class image:
def __init__(self, filePath='', options='', url=''):
self.client = AipImageClassify(APP_ID, API_KEY, SECRET_KEY)
# 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,
# 最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效
self.url = url
# 本地图像数据,base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式
self.image = ''
# 可选参数
self.options = options
if filePath:
# 读取图片
with open(filePath, 'rb') as fp:
self.image = fp.read()
def Recognition(self):
""" 调用通用物体识别 500次/天免费 """
return self.client.advancedGeneral(self.image, self.options)
3、创建login.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# pip install selenium
# pip install Image
# pip install baidu-aip
# pip install pyinstaller 安装pyinstaller,打包exe文件需要用到
# pyinstaller -F login.py 把python文件打包成exe文件,加上-w小写可以屏蔽黑窗口
import os
import re
import time
import baidu
from selenium import webdriver
from PIL import Image
i = 0
# 获取项目目录
path = os.path.abspath(os.path.dirname(__file__))
loginImage = path + "/image/login.png" # 登录页面截图
codeImage = path + "/image/code.png" # 定位验证码截图
base_url = '链接地址'
browser = webdriver.Chrome()
browser.maximize_window()
browser.implicitly_wait(10)
browser.get(base_url)
# (2) 输入账号密码
browser.find_element_by_id("username").send_keys("admin")
browser.find_element_by_id("password").send_keys("admin")
# time.sleep(2)
# 截图方法
def code_jt():
# (1)登录页面截图
browser.save_screenshot(loginImage) # 可以修改保存地址
# (3)获取图片验证码坐标
code_ele = browser.find_element_by_xpath('//img[@style="cursor:pointer;"]')
# print("验证码的坐标为:", code_ele.location)
# print("验证码的大小为:", code_ele.size)
# (4)图片4个点的坐标位置
left = code_ele.location['x'] # x点的坐标
top = code_ele.location['y'] # y点的坐标
right = code_ele.size['width'] + left # 上面右边点的坐标
down = code_ele.size['height'] + top # 下面右边点的坐标
image = Image.open(loginImage)
# (4)将图片验证码截取
code_image = image.crop((left, top, right, down))
code_image.save(codeImage) # 截取的验证码图片保存为新的文件
image = Image.open(codeImage)
img = image.convert('L') # P模式转换为L模式(灰度模式默认阈值127)
count = 165 # 设定阈值
table = []
for m in range(256):
if m < count:
table.append(0)
else:
table.append(1)
img = img.point(table, '1')
img.save(codeImage) # 保存处理后的验证码
def bd_img(i=0):
# 调用百度云接口
api = baidu.word(codeImage)
""" 调用通用文字识别, 50000次/天免费 """
results = api.General()
# print(results)
for result in results["words_result"]:
text = result["words"]
text = text.strip()
text = re.sub(r'[^A-Za-z0-9]+', '', text) # 替换特殊字符 re.match("^[a-zA-Z0-9]*$", text) and
if len(text) == 6:
print("正确" + str(i) + ":"+text)
browser.find_element_by_id("code").send_keys(text)
browser.find_element_by_xpath('//input[@type="submit"]').click() # 提交按钮查看按钮元素,click模拟点击提交
time.sleep(5) # 等待5秒,等待网页加载完成
# links = browser.find_element_by_xpath('//a[@class="checkin"]') # 点击签到
# links.click()
else:
print("错误" + str(i) + ":" + text)
browser.find_element_by_xpath('//img[@style="cursor:pointer;"]').click() # 提交按钮查看按钮元素,click模拟点击提交
if i > 10:
print('验证码获取失败')
exit(1)
else:
i += 1
code_jt()
bd_img(i)
code_jt()
bd_img(i)
4、打包程序
在py程序所在文件夹,打开cmd,输入pyinstaller -F login.py,打包为一个可运行程序,然后使用window的计划任务,就可以实现,定时签到,点赞等登录后的操作。
pyinstaller -D -w -i "D:\wwwroot\python\login\image\favicon.ico" login.py
如运行后报错:struct.error: unpack requires a buffer of 16 bytes
ico图标在线转换一下就可以了:www.ico51.cn/
pyinstaller相关参数
-F:生成一个文件夹,里面是多文件模式,启动快。
-D:仅仅生成一个文件,不暴露其他信息,启动较慢。
-w:窗口模式打包,不显示控制台。
-i:跟图标路径,作为应用icon。
5、Pyinstaller打包selenium去除chromedriver黑框问题解决!!!
解决方案就是修改selenium包中的service.py第76行
D:\wwwroot\python\Lib\site-packages\selenium\webdriver\common\service.py
try:
cmd = [self.path]
cmd.extend(self.command_line_args())
self.process = subprocess.Popen(cmd, env=self.env,
close_fds=platform.system() != 'Windows',
stdout=self.log_file,
stderr=self.log_file,
stdin=PIPE)
修改为:
try:
cmd = [self.path]
cmd.extend(self.command_line_args())
self.process = subprocess.Popen(cmd, env=self.env,
close_fds=platform.system() != 'Windows',
stdout=self.log_file,
stderr=self.log_file,
stdin=PIPE, creationflags=134217728)