目录
一、前言
主要目的:本篇博文主要是通过pyzbar实现扫码功能获取二维码链接,然后在微信中进入青年大学习。
笔者在还未实现从微信公众号进入青年大学习这个方法前,使用的就是这个方法;首先获取青年大学习的二维码,然后扫码,将链接内容发给“文件传输助手”(没有人愿意在调试的时候一直收到没用的网址),接下来打开网址进行后续操作。
二、前期准备
2.1代码模块准备
import time
import pyzbar.pyzbar as pyzbar
from PIL import Image
import subprocess
import uiautomation as auto
2.2二维码准备
首先进入青年大学习,然后点击学习记录(青年大学习-全国各省青年大学习入口)
不同省的有不同的学习入口,点击相应的二维码即可。
然后将该二维码截屏保存或者鼠标右键另存即可。 将图片保存为test.jpg
三、开干
3.1获取二维码信息
代码展示
# 1识别二维码
image = "test.jpg"
img = Image.open(image)
# 因为一张图片可能是一张二维码,也可能里面有许多二维码
barcodes = pyzbar.decode(img)
for barcode in barcodes:
barcodeData = barcode.data.decode("utf-8")
print(barcodeData)
首先将刚刚保存的test.jpg放到代码同一文件夹中。
然后使用PIL模块的Image.open()函数打开二维码,接着使用pyzbar.decode()解析图片信息,由于一张图片中可能包含多个二位码,因此需要遍历(固定模式,即即使图片里面只有一张二维码,还是需要这样写),接下来返回二维码data的信息。
这里笔者也不太清楚为啥,大家可以看下面的代码段,是pyzbar模块的decode()函数的具体代码。
def decode(image, symbols=None):
"""Decodes datamatrix barcodes in `image`.
Args:
image: `numpy.ndarray`, `PIL.Image` or tuple (pixels, width, height)
symbols: iter(ZBarSymbol) the symbol types to decode; if `None`, uses
`zbar`'s default behaviour, which is to decode all symbol types.
Returns:
:obj:`list` of :obj:`Decoded`: The values decoded from barcodes.
"""
pixels, width, height = _pixel_data(image)
results = []
with _image_scanner() as scanner:
if symbols:
# Disable all but the symbols of interest
disable = set(ZBarSymbol).difference(symbols)
for symbol in disable:
zbar_image_scanner_set_config(
scanner, symbol, ZBarConfig.CFG_ENABLE, 0
)
# I think it likely that zbar will detect all symbol types by
# default, in which case enabling the types of interest is
# redundant but it seems sensible to be over-cautious and enable
# them.
for symbol in symbols:
zbar_image_scanner_set_config(
scanner, symbol, ZBarConfig.CFG_ENABLE, 1
)
with _image() as img:
zbar_image_set_format(img, _FOURCC['L800'])
zbar_image_set_size(img, width, height)
zbar_image_set_data(img, cast(pixels, c_void_p), len(pixels), None)
decoded = zbar_scan_image(scanner, img)
if decoded < 0:
raise PyZbarError('Unsupported image format')
else:
results.extend(_decode_symbols(_symbols_for_image(img)))
return results
3.2打开“文件传输助手”
# 打开微信
subprocess.Popen('E:\微信\WeChat\WeChat.exe') # 可执行文件的具体地址信息
# 判断微信是否已经登录
wechat_login = auto.PaneControl(Name='微信')
enter_wechat_btn = wechat_login.ButtonControl(Name='进入微信')
if enter_wechat_btn.Exists():
enter_wechat_btn.Click()
wechatWindow = auto.WindowControl(searchDepth=1, className='WeChatMainWndForPC', Name='微信')
# 点击通讯录
button = wechatWindow.ButtonControl(Name='通讯录')
button.Click()
# 点击搜索
search = wechatWindow.EditControl(Name='搜索')
search.Click()
# 输入查找内容
# 通过遍历
search.GetParentControl().GetChildren()[1].SendKeys('文件传输助手')
searResult = wechatWindow.ListControl(Name='搜索结果').GetChildren()
for sear in searResult:
# print(sear.Name)
if sear.Name == '文件传输助手':
sear.Click()
break
wechatWindow.EditControl(Name='输入').SendKeys(barcodeData)
sendBtn = wechatWindow.ButtonControl(Name='sendBtn')
sendBtn.Click()
在输入框中输入获取到的网址,之后点击发送(s)。
3.3获取最新消息
如上图所示,最新发的消息为“消息”列表中最后面一个
接下来网址具体在EditControl控件中,因此我们可以通过树一层层的查找。
messages = wechatWindow.ListControl(Name="消息")
# 到达最新消息的url窗格
message = messages.GetChildren()[-1]
message1 = message.GetChildren()[0]
message2 = message1.GetChildren()[1]
message3 = message2.GetChildren()[0]
message4 = message3.GetChildren()[0]
message5 = message4.GetChildren()[0]
message6 = message5.GetChildren()[0]
message6.Click()
如果嫌麻烦,也可以直接根据控件类型查找。
messages = wechatWindow.ListControl(Name="消息")
# 到达最新消息的url窗格
message = messages.GetChildren()[-1]
url = message.EditControl()
url.Click()
注意:由于每次的网址可能不同,因此不能根据Name来定位控件。
3.4“青年大学习”页面操作
接下来就是进入“青年大学习”页面进行具体操作了,详情解析请看之前写的文章,
在学uiautomation(以微信进入青年大学习为例)
具体代码如下,
wechatWindow_2 = auto.WindowControl(searchDepth=1, className='CefWebViewWnd', Name='微信')
# 判断是否为最大化
restore = wechatWindow_2.ButtonControl(Name='向下还原')
if restore.Exists():
restore.Click()
agree_btn = wechatWindow_2.ButtonControl(Name="同意")
# 这个判断会花费较长时间
if agree_btn.Exists():
agree_btn.Click()
study_icon = wechatWindow_2.ImageControl(Name='立即学习')
study_icon.Click()
# 到达立即参与界面
participate_in_btn = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[4].GetChildren()[0]
participate_in_btn.Click()
# # 到达立即学习界面
study_page = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[3].GetChildren()[0]
time.sleep(5)
study_btn = study_page.GetChildren()[9]
study_btn.Click()
max_page = wechatWindow_2.ButtonControl(Name='最大化')
max_page.Click()
time.sleep(2)
edit = wechatWindow_2.EditControl(searchDepth=5).GetValuePattern().Value
print(edit)
# 向下还原
restore_page = wechatWindow_2.ButtonControl(Name='向下还原')
restore_page.Click()
3.5页面的关闭
# 关闭青年大学习页面
wechatWindow_2.ButtonControl(Name='关闭').Click()
# 关闭微信界面
wechatWindow.ButtonControl(Name='关闭').Click()
3.6全部代码展示
# -*- coding: utf-8-*-
import time
import pyzbar.pyzbar as pyzbar
from PIL import Image
import subprocess
import uiautomation as auto
# 1识别二维码
image = "test.jpg"
img = Image.open(image)
# 因为一张图片可能是一张二维码,也可能里面有许多二维码
barcodes = pyzbar.decode(img)
for barcode in barcodes:
barcodeData = barcode.data.decode("utf-8")
print(barcodeData)
# 打开微信
subprocess.Popen('E:\微信\WeChat\WeChat.exe') # 可执行文件的具体地址信息
# 判断微信是否已经登录
wechat_login = auto.PaneControl(Name='微信')
enter_wechat_btn = wechat_login.ButtonControl(Name='进入微信')
if enter_wechat_btn.Exists():
enter_wechat_btn.Click()
wechatWindow = auto.WindowControl(searchDepth=1, className='WeChatMainWndForPC', Name='微信')
# 点击通讯录
button = wechatWindow.ButtonControl(Name='通讯录')
button.Click()
# 点击搜索
search = wechatWindow.EditControl(Name='搜索')
search.Click()
# 输入查找内容
# 通过遍历
search.GetParentControl().GetChildren()[1].SendKeys('文件传输助手')
searResult = wechatWindow.ListControl(Name='搜索结果').GetChildren()
for sear in searResult:
# print(sear.Name)
if sear.Name == '文件传输助手':
sear.Click()
break
wechatWindow.EditControl(Name='输入').SendKeys(barcodeData)
sendBtn = wechatWindow.ButtonControl(Name='sendBtn')
sendBtn.Click()
messages = wechatWindow.ListControl(Name="消息")
# # 到达最新消息的url窗格
# message = messages.GetChildren()[-1]
# message1 = message.GetChildren()[0]
# message2 = message1.GetChildren()[1]
# message3 = message2.GetChildren()[0]
# message4 = message3.GetChildren()[0]
# message5 = message4.GetChildren()[0]
# message6 = message5.GetChildren()[0]
# message6.Click()
# 到达最新消息的url窗格
message = messages.GetChildren()[-1]
url = message.EditControl()
url.Click()
wechatWindow_2 = auto.WindowControl(searchDepth=1, className='CefWebViewWnd', Name='微信')
# 判断是否为最大化
restore = wechatWindow_2.ButtonControl(Name='向下还原')
if restore.Exists():
restore.Click()
agree_btn = wechatWindow_2.ButtonControl(Name="同意")
# 这个判断会花费较长时间
if agree_btn.Exists():
agree_btn.Click()
study_icon = wechatWindow_2.ImageControl(Name='立即学习')
study_icon.Click()
# 到达立即参与界面
participate_in_btn = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[4].GetChildren()[0]
participate_in_btn.Click()
# # 到达立即学习界面
study_page = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[3].GetChildren()[0]
time.sleep(5)
study_btn = study_page.GetChildren()[9]
study_btn.Click()
max_page = wechatWindow_2.ButtonControl(Name='最大化')
max_page.Click()
time.sleep(2)
edit = wechatWindow_2.EditControl(searchDepth=5).GetValuePattern().Value
print(edit)
# 向下还原
restore_page = wechatWindow_2.ButtonControl(Name='向下还原')
restore_page.Click()
# 关闭青年大学习页面
wechatWindow_2.ButtonControl(Name='关闭').Click()
# 关闭微信界面
wechatWindow.ButtonControl(Name='关闭').Click()
四、总结
①上述内容与之前写的最主要的区别是进入微信青年大学习的方式不同,之前的是通过公众号进入,这次采用网址进入。各有优缺点吧,不过都能学到新的内容。
②上述内容如有错误,请指正!!
③下期内容预告:青年大学习15倍速播放,敬请期待!!