前言:
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 日一天的数据。