前言:
1.由于突如其来的疫情,让春节假期延长了将近一个月,才有时间去做这件事。
2.面对疫情人类是如此的脆弱,自身抵抗力成为战胜此次病毒的关键,加油!
3.全国范围内禁止外出,都窝在家里刷微博,看电视,了解疫情。
4.通过获取微信好友运动数据,可以分析好友步数动态变化。
1.由于突如其来的疫情,让春节假期延长了将近一个月,才有时间去做这件事。
2.面对疫情人类是如此的脆弱,自身抵抗力成为战胜此次病毒的关键,加油!
3.全国范围内禁止外出,都窝在家里刷微博,看电视,了解疫情。
4.通过获取微信好友运动数据,可以分析好友步数动态变化。
流程:
1.电脑与手机互通;
2.定时获取微信运动数据;
3.数据图形显示;
1.电脑与手机互通;
2.定时获取微信运动数据;
3.数据图形显示;
一、电脑与手机互通
1、安装 appium、jar、android-sdk 等
2、显示设备 adb devices
包名 adb shell dumpsys window | findstr windows
安卓版本 adb shell getprop ro.build.version.release
3、使用 uiautomatorviewer 获取微信元素信息(失败时,可通过下方手动获取。)
手动获取
adb shell uiautomator dump /sdcard/app.uix
adb pull /sdcard/app.uix E:/app.uix
adb shell screencap -p /sdcard/app.png
adb pull /sdcard/app.png E:/app.png
1、安装 appium、jar、android-sdk 等
2、显示设备 adb devices
包名 adb shell dumpsys window | findstr windows
安卓版本 adb shell getprop ro.build.version.release
3、使用 uiautomatorviewer 获取微信元素信息(失败时,可通过下方手动获取。)
手动获取
adb shell uiautomator dump /sdcard/app.uix
adb pull /sdcard/app.uix E:/app.uix
adb shell screencap -p /sdcard/app.png
adb pull /sdcard/app.png E:/app.png
二、代码
1、获取微信数据。
1、获取微信数据。
from appium import webdriver from selenium.webdriver.support.ui import WebDriverWait from appium.webdriver.common.touch_action import TouchAction import parsel import datetime import time import json def crawl(desired_caps): data = {} #存储排行榜的信息 num = 0 #时间计数 name_list = [] # 好友昵称 run_count_list = [] # 步数列表 flag = 1 # 自己在第一位,排除掉 i = 0 date = datetime.datetime.now().strftime("%H:%M") driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) wait = WebDriverWait(driver, 30, 5) # 设置显示等待,即 30 秒内,每隔 5 秒找一次元素 TouchAction(driver).tap(element=wait.until(lambda x: x.find_element_by_xpath('//*[@text="微信运动"]'))).perform() TouchAction(driver).tap(element=wait.until(lambda x: x.find_element_by_xpath('//*[@text="步数排行榜"]'))).perform() while True: # 防止长时间运行中断,改成每次获取都重新连接! if driver.find_elements_by_xpath('//*[@text="邀请朋友"]') == []: #判断是否到底 driver.swipe(480,1500,480,700,duration=2000) #滑动 response = parsel.Selector(driver.page_source) if flag == 1 : people = response.xpath('//*[@resource-id="com.tencent.mm:id/om"]')[1:] else: people = response.xpath('//*[@resource-id="com.tencent.mm:id/om"]') for eachone in people: flag = 0 name = eachone.xpath('.//*[@resource-id="com.tencent.mm:id/brk"]/@text').get() # 注意这里用的是@text,而不是/text,之前我在这里都快绝望了,一直拿不到 text 的内容,最后给蒙出来了哈哈 run_count = eachone.xpath('.//*[@resource-id="com.tencent.mm:id/bq8"]/@text').get() like = eachone.xpath('.//*[@resource-id="com.tencent.mm:id/bpy"]/@text').get() if (name not in name_list) and (name is not None): info = [name, run_count, like] temp = [] # 存储步数和点赞数 name_list.append(name) temp.append(run_count) temp.append(like) run_count_list.append(temp) i +=1 date_now = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") print('<', i, '>', date_now, ':', info) item = dict(zip(name_list, run_count_list)) data.update({date: item}) else: break num += 1 print(f'{date}:第{num}次检测到{len(name_list)}个好友开始了微信运动!') driver.quit() # 退出 data_name = datetime.datetime.now().strftime("%Y%m%d%H%M") data_name = "%s.json"%data_name json_str = json.dumps(data, indent=4, ensure_ascii=False) with open(data_name, 'w', encoding='utf-8') as f: f.write(json_str) f.close() def ex_error(desired_caps): heart_times = 0 while True: date_times = int(datetime.datetime.now().strftime("%M")) if date_times == 0 or date_times == 30: try: crawl(desired_caps) except: print('ERROR!') time.sleep(30) crawl(desired_caps) else: heart_times += 1 date_times_now = datetime.datetime.now().strftime("%H:%M") print(f'----------------({date_times_now}-{heart_times})-------------------') time.sleep(30) if __name__ == '__main__': desired_caps = { 'platformName': 'Android', # 操作系统 'deviceName': '1d0eb1a2', # 设备名 # 'deviceName': 'emulator - 5554', 'platformVersion': '10', # 版本号 'appPackage': 'com.tencent.mm', # 包名 'appActivity': 'com.tencent.mm.ui.LauncherUI', # 界面名 'noReset':'True' } ex_error(desired_caps)
2、数据处理
import pandas as pd import random import json import os import matplotlib import matplotlib.pyplot as plt #画图工具 plt.rcParams['font.sans-serif'] = ['SimHei'] #黑体(显示中文) plt.rcParams['font.size'] = 20 #字体大小 #加载 json 数据 with open('202002071.json','r',encoding='utf-8') as f: data=json.load(f) def everyone_plot(name): run_count_list = [] # 存储步数 like_list = [] # 存储点赞数 for i in list(data.keys()): if data[i].get(name) is not None: run_count = int(data[i].get(name)[0]) run_count_list.append(run_count) like_list.append(int(data[i].get(name)[1])) else: run_count_list.append(0) like_list.append(0) plt.figure(figsize=(18, 8)) plt.plot(list(data.keys()), run_count_list, label='步数', linewidth=2, color='blue', marker='o', markerfacecolor='red', markersize=8) plt.tick_params(axis='x', rotation=70) plt.ylabel('步数/步') plt.title(f'{name}的个人运动趋势') low = 0 if min(run_count_list) < 1000 else 250 high = max(run_count_list) + max(run_count_list) / 2 plt.ylim(low, high) plt.grid(True) for x, y in zip(list(data.keys()), run_count_list): plt.text(x, y, y, ha='center', va='bottom', fontsize=18) for i, (x, y) in enumerate(zip(list(data.keys()), run_count_list)): if like_list[i] != 0: plt.text(x, low, f'{like_list[i]}赞', ha='center', va='bottom', fontsize=18) plt.legend() plt.tight_layout() # 铺满整个画布 plt.savefig(f'./personal/{name}.jpg') plt.show() if __name__ == '__main__': if not os.path.exists('./personal'): os.makedirs('./personal') all_name = [] # 存储这些数据里面出现过的所有人的姓名 for i in list(data.keys()): all_name += list(data[i].keys()) all_name = list(set(all_name)) # 集合去重法 for i in range(len(all_name)): eachone = random.choice(all_name) all_name.remove(eachone) everyone_plot(eachone)
正常好友运动数据
奇葩好友运动数据
注意:以上数据选取的是 2020 年 2 月 8 日一天的数据。