首页 >> 大全

py征途4之无效思路

2023-08-17 大全 30 作者:考证青年

事件回顾:

近期班里组织了一个跑团,使用的是keep跑团助手(小程序)。每个人都有一个昵称,要对“每日跑量”进行统计,以明确到底有哪些人跑了步,哪些人没跑步。

为了解决这个问题,从3月28日(晚)到4月2日(早),共历时4天半,期间诞生了很多思路,学习了很多知识,下面 一 一 分享复盘一下。

思路 三,初识逆向 四, 五,后记

一,抓包获取api

在网上主流的有两种,一种是,一种是,经过一天的研究我选择了。

微信小程序抓包(详解)

但是抓包得到的结果却不尽人意,很明显,抓到的报文都是经过动态加密的。尝试根据抓包得到的url构造api也失败了,要么是404,要么是error。

最终还是放弃了抓包的思路,不过,至少会使用了,不是吗?

二,图片识别

随着跑团第一次活动的开展,每周要统计两次参与人员,那时是第一周的周二,我迎来了第一个挑战——当时我通过图片识别昵称,然后匹配字典来解决。

想法很美好,显示很骨感。

备注:一定要关闭vpn在运行代码。

自动识别图片文字—保姆级OCR实战教程

通过这段教程,我学习到了cnocr和两个图片文字识别库。使用cnocr的过程不是很愉悦,因为,它不支持长图识别,并且上下行文字之间不能有较大的留白,基本识别不出内容。

2百度api

本着什么简单,什么上的想法,我去注册了个百度api的账号。

调用百度ocr接口,实现图片内文字识别

根据这个教程我创建了应用,经过测试,不得不说,体验很一般(暗人不说明话),识别结果一团糟,即:“有,但是不准确”。

最终还是选择了。

分两步:

1 pip

2 -OCR的安装和使用

使用它,我坎坷的完成了这次挑战,但期间仍然出现了很多非预期,下面是个例子,以及我当时的解决思路。

# str1="小姜鸡39"
# str2="小辣圾39"
def like_standard(str1, str2):like_value = 0if len(str1) == len(str2):#如果长度相等,相似值加1like_value += 1for i in range(len(str1)):if str1[i:i+3] in str2:#三个字符三个字符增加相似值like_value += 1if like_value >= 2:#相似值至少大于3return Trueelse:return False

尝试使用相似值来“归纳”识别结果,但最终统计出来的数据会出现1-2个bug,无论怎么修正相似值任然会出现各种各样的非预期。

4图片分割

为了提高识别的精准度,我还是去学习了cv2的图片分割方法,这个代码是我让写的,然后我只是修改了他写错的地方。

import cv2img = cv2.imread('C:\\Users\\qte\\Desktop\\Screenshot_20230331_215023.jpg')# 指定图像路径并读取图像
img_height = img.shape[0]# 获取图像的高度。shape[0]是高度,shape[1]是宽度
#segment_size = 150#确定分割的大小,以像素为单位,例如每150像素分割一次:
segment_size=1180#这个像素似乎不会出现将一个名字分到两张图片
print(segment_size)
count = 1for i in range(0,img_height,segment_size):print(i)segment = img[i:i+segment_size,:]cv2.imwrite(f'C:\\Users\\qte\\Desktop\\123\\segment{count}.jpg', segment)count += 1

在这个过程中我还解决了后续识别和分类的代码,以下这段代码将统计哪些人跑了,哪些人没跑。

class_all = [...]#这个列表记录了同学的信息
class_name = {...:...}#这个字典记录了昵称的对应关系
list_paole = []
for i in text1:#print(i)  # 输出识别结果for k in class_name.keys():if i.upper() == k.upper() or like_standard(i.upper(),k.upper()):  #精准匹配+自写函数模糊匹配#print(like_standard(i,k))print(k)  # 输出匹配上的识别结果if class_name[k] == "1":print(i)list_paole.append(i)else:print(class_name[k])list_paole.append(class_name[k])print(list_paole)
re_class = [x for x in class_all if x not in list_paole]
print(re_class)# list1 = [1,2,3,4]
# list2 = [3,4,5,6]
# list3 = [x for x in list1 if x not in list2]print(list3)#[1,2]
# list1中的1和2都不在list2中,而3和4则在list2中,所以执行list 减法后,生成的list3中只包含list1中不在list2中的1和2

即便如此我还是不甘心,这并没有在实际上解决问题,因为图片分割是不稳定的,他会因为图片的不同而出现意外情况。

三,初识逆向

偶然间我看到了这样两篇文章

实用的微信小程序逆向教程!

记一次小程序逆向和数据包解密

因为国内工具被删了,只好用国外的了。

刚好近期学了,kali里面有node环境,然后,我“逆向”出了该微信小程序的源码。当然了期间总会遇到些小问题,都还算顺利的解决了。

1源码审计

因为方法较为特殊就不放代码的截图了,主要讲一讲大致的历程吧。兜兜转转了很久,找到了主要显示“每日跑量”的index.js和index.wxml,但是没有发现调库的痕迹。还是代码知识太浅薄了,可能是第一次接触微信小程序吧,没有真正做过小程序。

2来自PMR的支援

马上就要体能了,刚好P佬不是很擅长锻炼,于是我就拉着它去跑步,顺道提到了这个事情,一来二去,就讨论了起来。Ta指出“微信小程序逆向之后得到的并不是真实源码,它们是经过了微信的处理后生成的,分析起来比较难”。然后Ta给我提供了一个思路——抓取的控件。

四, 1控件!!!!!

在使用查看布局后可以发现,这里面有个一text标签详细记录了昵称,那么我只要获取到这个控件的text就行或者直接获取该控件的全部信息也可以。

通过默认的选项生成代码,然后修改为获取全部变量即可。

(".view.View").text("这周末在做梦13").()

将他修改为

(".view.View").find()

然后写入日志文件。

files.remove("/sdcard/Pictures/运行日志2.txt");
//app.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, android.net.Uri.fromFile(java.io.File("/sdcard/Pictures/运行日志1.txt"))));
var name = className("android.view.View").find();
console.setGlobalLogConfig({ "file": "/sdcard/Pictures/运行日志2.txt" });
console.log(name);

这样就可以获取到当前页面所有控件的信息了。

2配置环境

参考这篇文章配置。

Auto.js的初次使用——在中使用

其中还是有部分步骤不一样的,需要学习的小伙伴可以参考下面这张我总结的图片

3用最傻的方式做最聪明的事情

(1)将日志文件输出到PC,调用进行字符串处理。

当时是因为懒得去学习的相关语法,感觉没有用的顺手于是就直接写了。

log_path="C://Users//qte//Nox_share//ImageShare//运行日志1.txt"
f = open(log_path, 'r',encoding='utf-8')
#print(f.read())
str_log=f.read()
f.close()str_last=[]#记录最终日志分割后的列表
#根据'text: '和'; content'分割日志
str_log_list=str_log.split('text: ')
for i in str_log_list:i=i.split('; content')#print(i[0])str_last.append(i[0])#经过两次分割,掐头去尾,个i列表的第一个就是昵称。当然了,不排除可能出现其他非昵称字符的情况,但这种情况会在接下来的代码中解决。
print(str_last)
"""
以下这一段就是后续识别和分类的代码,和之前介绍的一样,只是去掉了like_standard。
"""
list_paole = []
for i in str_last:for k in class_name.keys():if i == k:  #匹配相等就输出#print(like_standard(i,k))print(k)  # 输出匹配上的识别结果if class_name[k] == "1":print(i)list_paole.append(i)else:print(class_name[k])list_paole.append(class_name[k])print(list_paole,len(list_paole))
re_class = [x for x in class_all if x not in list_paole]
print(re_class)

(2)P佬指出你为啥不直接用一个脚本跑完呢?

对哦,然后我就让将这段代码“翻译”了一下,这次他竟然出奇的正确,没有出现任何语法错误。

但是要提取控价,是需要分层的,然后根据布局来确定深度…P神佬给出了一个方案:

(3)用最傻的方式将代码集成到1个atuo脚本。

但是我就是懒,不愿意去学习的输出流。之前不是已经把这些控件信息写到了txt文件嘛,然后也“翻译”好了嘛,干脆在读出来呗。

于是乎就用这样最傻的方式解决了这个问题,最终这个脚本里只有“var name = ”这11个字符,emmm,外加4个分号是我自己写的。

五,后记

事后我得到了p佬的“肯定”。

当然了,其实只要将var name赋给就行了,也不需要研究什么输出流,不过具体代码就不展示在这篇文章里了。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了