• 一首歌可以循环一整天《我们都是好孩子》
  • 在别人眼里是逃避,其实是不想牵累任何人,做孤独的自己。
  • 也许有一天我会背着包,独自漂流。
  • 既然做了决定,就不后悔,再见昆明!
  • 愿闻世间百态。
  • 外表的一切如常,内心的混乱又有谁能了解!
  • 突然想回安徽工作了!
  • 该来的还是来了,Uzi宣布退役!
  • 国内疫情已完全控制住,但是国外疫情大爆发,现在开始限制人员入境。
  • 啊啊啊,IP被墙了,好烦!

Python获取微信运动数据,并生成折线图

程序 愿闻世间百态 5年前 (2020-05-14 13:06:49) 10464次浏览 已收录 143个评论

流程:
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、获取微信数据。

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)

正常好友运动数据

Python 获取微信运动数据,并生成折线图
奇葩好友运动数据

Python 获取微信运动数据,并生成折线图
注意:以上数据选取的是 2020 年 2 月 8 日一天的数据。


WECV.CN , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python 获取微信运动数据,并生成折线图
喜欢 (0)
[]
分享 (0)

您必须 登录 才能发表评论!

(143)个小伙伴在吐槽