手撸了一个全自动微信清粉小工具(源码详解)

简介: 微信清理僵尸粉工具利用Python和`uiautomator2`库,通过模拟转账操作自动检测并标记微信好友列表中被删除、被拉黑或账号存在问题的“僵尸粉”。工具支持开启调试模式、自动打开微信、获取好友信息、判断好友状态、管理标签等功能,最终将检测结果记录到文件中,便于用户管理和清理好友列表。此工具适用于Android设备,已在OPPO Reno4 Pro上测试成功。

在当今社交软件中,微信是最常用的通讯工具之一。然而,随着时间的推移,我们的好友列表中可能会出现一些不再活跃的账号,也就是我们俗称的“僵尸粉”。

这些账号可能是由于长时间不使用、账号被封禁或者故意将我们删除或拉黑。为了保持好友列表的清洁和有效沟通,同时也为了帮助我们更好地管理微信好友,最近我使用 Python 和 uiautomator2 库编写了一个自动化工具来清理这些僵尸粉。

这个工具会通过检测好友的状态(如是否被删除、是否被拉黑或是否账号出现问题)来批量标记并处理这些好友。

这个工具的主要功能包括:

  • 识别被删除或拉黑的好友:通过模拟转账操作,检查与好友的交易是否正常。
  • 标记问题账号:对于账号存在问题(如被封禁、拉黑、删除)的好友进行标记。
  • 记录和输出结果:将检查结果记录到文件中,方便后续查看和管理。

接下来,我将从代码的整体结构开始分析,介绍如何使用 uiautomator2 来控制 Android 设备,并通过自动化方式清理微信中的僵尸粉。

需要注意的是:因为我手头上只有一部 OPPO Reno4 Pro 安卓手机,因此只能在这部手机上做了实验。不太确定是否在其他机型上有无问题。

核心类和初始化

这段代码定义了一个名为 WXCleanFriends 的类,该类包含了所有执行清理操作的核心方法。类内部包含多个常量和状态标记,用于表示不同的好友状态,如正常、被删除、被拉黑等。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
微信清理僵尸粉工具
通过遍历微信好友列表,将僵尸粉(被删除、被拉黑、账号问题)进行标记
"""
import json
import time

import uiautomator2 as u2
from uiautomator2 import Direction


class WXCleanFriends:
    """
    微信清理僵尸粉
    运行设备为:OPPO Reno4 pro
    """

    # 检查好友状态时,如果是被对方删除的话,需要打上的标签
    TAG_HAS_DELETED = '清粉-被删除'
    # 检查好友状态时,如果是被对方拉黑的话,需要打上的标签
    TAG_HAS_BLACK = '清粉-被拉黑'
    # 检查好友状态时,如果是对方账号出现问题的话,需要打上的标签
    TAG_ACCOUNT_PROBLEM = '清粉-账号问题'

    # 好友状态
    FRIEND_STATUS_NORMAL = 'normal'  # 正常
    FRIEND_STATUS_HAS_DELETED = 'has_deleted'  # 被删除
    FRIEND_STATUS_HAS_BLACK = 'has_black'  # 被拉黑
    FRIEND_STATUS_ACCOUNT_PROBLEM = 'account_problem'  # 账号问题
    FRIEND_STATUS_UNKNOWN = 'unknown'  # 未知

    # 给好友打标签情况
    TAG_NEVER_REMARK = 'never_remark'  # 从来没有打过标签
    TAG_HAS_JOIN = 'has_join'  # 已经加入过该标签群组
    TAG_HAS_REMARK_OTHER = 'has_remark_other'  # 已经打过标签,但不是【{tag_name}】标签

    def __init__(self,
                 last_friend_wx_code: str,
                 ignore_wx_code: list,
                 max_page_get_friend_list: int = 8
                 ):
        """
        :param last_friend_wx_code: 通讯录中最后一个好友的微信号
        :param ignore_wx_code: 需要被忽略检测的微信号或者微信昵称
        :param max_page_get_friend_list: 检查通讯录中的好友列表最大页数
        """

        # 连接设备
        self.d = u2.connect()
        # 被检查的好友列表(可以理解成所有的好友)
        self.friends_list = []
        # 记录当前已经被检测过的好友,避免重复检测
        self.friends_has_checked = {
   }

        # 通讯录中最后一个好友的微信号
        self.last_friend_wx_code = last_friend_wx_code
        # 需要被忽略检测的微信号或者微信昵称
        self.ignore_wx_code = ignore_wx_code
        self.max_page_get_friend_list = max_page_get_friend_list

    def enable_debug(self):
        """
        开启调试模式
        :return:
        """

        # 开启日志
        # u2.enable_pretty_logging()
        # 设置 http 请求超时时间
        u2.HTTP_TIMEOUT = 60
        # 开启调试模式
        # self.d.debug = True

        print(f"设备信息 ==> {self.d.info}")
        print(f"设备IP ==> {self.d.wlan_ip} 设备号 ==> {self.d.serial}")

        # 设置查找元素等待时间,单位秒
        self.d.implicitly_wait(30)

        # UI 层次结构
        # xml = d.dump_hierarchy(compressed=False, pretty=True, max_depth=50)
        # print(xml)

初始化方法接受三个参数:

  • last_friend_wx_code:通讯录中最后一个好友的微信号,用于确定清理到哪个位置停止。
  • ignore_wx_code:一个列表,包含了需要跳过检查的微信号或昵称。
  • max_page_get_friend_list:最多获取多少页的好友列表,避免检测过多的好友。

自动化打开微信

    def weixin_start(self):
        """
        打开微信
        :return:
        """
        # self.d.xpath('//android.widget.TextView[@text="微信"]').click(5)

        wx_app = self.d(text='微信', className='android.widget.TextView')
        if wx_app.exists() is False:
            print('当前页面没有微信 APP,请切换到有微信 APP 的页面')
            exit(1)

        print("打开微信")
        wx_app.click(timeout=5)

weixin_start 方法用于启动微信应用。它通过 uiautomator2 来模拟点击操作。如果当前页面没有找到微信应用,程序将退出。

获取好友信息和状态判断

    def get_personal_info(self):
        """
        获取好友个人信息
        :return:
        """
        remark = nickname = wx_code = zone = tag = ''

        remark_elem = self.d(className='android.widget.TextView', resourceId='com.tencent.mm:id/cf8')
        if remark_elem.exists(timeout=3):
            remark = remark_elem.get_text()

        nickname_elem = self.d(className='android.widget.TextView', resourceId='com.tencent.mm:id/cf7')
        if nickname_elem.exists(timeout=3):
            nickname = nickname_elem.get_text().lstrip('昵称:  ')

        wx_code_elem = self.d(className='android.widget.TextView', resourceId='com.tencent.mm:id/cff')
        if wx_code_elem.exists(timeout=3):
            wx_code = wx_code_elem.get_text().lstrip('微信号:  ')

        zone_elem = self.d(className='android.widget.TextView', resourceId='com.tencent.mm:id/cf6')
        if zone_elem.exists(timeout=3):
            zone = zone_elem.get_text().lstrip('地区:  ')

        tag_elem = self.d(className='android.widget.TextView', resourceId='com.tencent.mm:id/cd4')
        if tag_elem.exists(timeout=3):
            tag = tag_elem.get_text()

        print(
            f"备注名是[{remark}] 昵称是[{nickname}] 微信号是[{wx_code}] 地区是[{zone}] 标签是[{tag}]")

        return {
   'remark': remark, 'nickname': nickname, 'wx_code': wx_code, 'zone': zone, 'tag': tag}

get_personal_info 方法通过定位 UI 元素来提取好友的个人信息,包括备注名、昵称、微信号、地区和标签等。

    def judge_friend_status(self) -> str:
        """
        判断当前好友的状态
        :return:
        """
        # 点击【发消息】按钮
        if self.d(text='发消息').click_exists(10) == False:
            # if self.d(resourceId='com.tencent.mm:id/cfb').click_exists(timeout=10) == False:
            print('没有点击【发消息】按钮')
            exit()
        # 点击【➕】
        if self.d(resourceId='com.tencent.mm:id/bjz').click_exists(timeout=10) == False:
            print('没有点击【➕】按钮')
            exit()
        # 点击【转账】按钮
        if self.d(resourceId='com.tencent.mm:id/a12', text='转账').click_exists(timeout=10) == False:
            print('没有点击【转账】按钮')
            exit()

        time.sleep(1)

        # 先清空转账金额,以免导致金额输入错误或者输入大额金额
        self.d(resourceId='com.tencent.mm:id/pbn').clear_text(3)
        # 输入 0.01 元 ---> start
        self.d(resourceId='com.tencent.mm:id/keyboard_0').click_exists(3)
        self.d(resourceId='com.tencent.mm:id/keyboard_dot').click_exists(3)
        self.d(resourceId='com.tencent.mm:id/keyboard_0').click_exists(3)
        self.d(resourceId='com.tencent.mm:id/keyboard_1').click_exists(3)
        # 输入 0.01 元 ---> end
        time.sleep(1)
        # # 点击【转账】按钮
        self.d(resourceId='com.tencent.mm:id/keyboard_action', text='转账').click_exists(3)

        # 点击转账之后,就可以根据页面元素来判断当前好友的状态

        # 1、如果页面中存在【¥0.01】元素,证明当前好友没有将自己删除
        is_normal = self.d(text='¥0.01', className='android.widget.TextView').exists(timeout=3)
        if is_normal is True:
            return self.FRIEND_STATUS_NORMAL

        # 判断是否有弹窗
        alert_elem = self.d(resourceId='com.tencent.mm:id/jlg')
        if alert_elem.exists(timeout=5):
            time.sleep(2)
            # 有弹窗的情况下,通过弹窗中的文本内容来判断当前好友的状态
            alert_text = alert_elem.get_text()
            # 2、判断是否被拉黑
            if '请确认你和他(她)的好友关系是否正常' in alert_text:
                return self.FRIEND_STATUS_HAS_BLACK
            # 3、判断是否被删除
            if '你不是收款方好友,对方添加你为好友后才能发起转账' in alert_text:
                return self.FRIEND_STATUS_HAS_DELETED
            # 4、判断是否被限制登录(对方的账号可能出现了问题、该账号已无法使用)
            if ('对方微信号已被限制登录,为保障你的资金安全,暂时无法完成交易。' in alert_text
                    or '当前使用人数过多,请稍后再试。' in alert_text
                    or '对方账户有异常行为,已被限制收款,本次交易无法完成。对方可通过微信支付公众号上收到的消息查看详情。' in alert_text
            ):
                return self.FRIEND_STATUS_ACCOUNT_PROBLEM

        # 5、其他情况(未知)
        return self.FRIEND_STATUS_UNKNOWN

judge_friend_status 方法通过一系列点击操作模拟转账行为,根据页面弹窗判断好友的状态。主要判断的状态包括:

  • 正常状态:好友未删除,未拉黑,账号正常。
  • 被删除:如果弹出提示“你不是收款方好友”,则说明好友已删除。
  • 被拉黑:如果出现“请确认你和他(她)的好友关系是否正常”,则说明好友将你拉黑。
  • 账号问题:如果弹窗提示账户已被限制登录,则说明对方账号存在问题。

标签管理

    def has_join_tag_group(self, tag_name: str) -> str:
        """
        判断当前用户是否已经被打了某个标签
        :param tag_name: 标签名称 eg: 清粉-被删除
        :return: never_remark: 从来没有打过标签
                    has_join: 已经加入过该标签群组
                    has_remark_other: 已经打过标签,但不是【{tag_name}】标签
        """
        # 好友资料页面中的【标签】属性
        tag_elem = self.d(className='android.widget.TextView', resourceId='com.tencent.mm:id/cd4')

        if tag_elem.exists(timeout=5) is False:
            print(f'没有找到标签元素,证明没有对该好友打过任何标签,现在需要对该好友打上【{tag_name}】标签')
            # 证明没有给该好友打过任何标签
            return self.TAG_NEVER_REMARK

        # 获取标签元素的文本
        tags = tag_elem.get_text()
        if tag_name in tags:
            print(f'已经加入过【{tag_name}】群组')
            # 证明已经加入过该标签群组
            return self.TAG_HAS_JOIN
        else:
            # 证明已经打过标签,但不是【{tag_name}】标签
            print(f'已经打过标签,但不是【{tag_name}】标签,现在需要对该好友打上【{tag_name}】标签')
            return self.TAG_HAS_REMARK_OTHER

    def join_tag_group(self, tag_name: str):
        """
        加入标签群组
        :param tag_name: 标签名称 eg: 清粉-被删除
        :return:
        """
        print(f'开始加入【{tag_name}】标签群组')

        # 这里有 2 种情况:
        # 一种是之前加过标签的,那么则有“标签”;
        # 一种是没有加过标签的,那么则有“设置备注和标签”
        # 好友资料页面中的【标签】
        tag_zone = self.d(resourceId='com.tencent.mm:id/cd5', text='标签')
        if tag_zone.exists(timeout=5) is False:
            print('之前没有给该好友打过任何标签')
            tag_zone = self.d(className='android.widget.TextView', resourceId='android:id/title', text='设置备注和标签')
            if tag_zone.exists(timeout=5) is False:
                print('没有找到【设置备注和标签】按钮')
                exit()

        tag_zone.click(timeout=1)
        # 【设置备注和标签】页面中的【标签】去添加标签
        self.d(resourceId='com.tencent.mm:id/cd8').click(timeout=1)

        # 在标签列表中查找是否有【{tag_name}】标签
        target_tag_elem = self.d(text=tag_name, className='android.widget.TextView')

        if target_tag_elem.exists(timeout=1) is False:
            print(f"没有找到【{tag_name}】标签,现在需要创建【{tag_name}】标签")
            # 点击【新建标签】按钮
            self.d(resourceId='com.tencent.mm:id/k70', text='新建标签').click(timeout=1)
            create_tag = self.d(resourceId='com.tencent.mm:id/d98', text='标签名称')
            create_tag.clear_text(timeout=1)
            create_tag.set_text(tag_name, 1)
            time.sleep(1)
            self.d(resourceId='com.tencent.mm:id/kao', text='确定').click(timeout=1)
            time.sleep(1)
            self.d(resourceId='com.tencent.mm:id/fp', text='保存').click(timeout=1)
            time.sleep(1)
            self.d(resourceId='com.tencent.mm:id/fp', text='完成').click(timeout=1)
        else:
            print(f"已经存在【{tag_name}】标签,现在只需要添加")
            target_tag_elem.click(timeout=1)
            time.sleep(1)
            self.d(resourceId='com.tencent.mm:id/fp', text='保存').click(timeout=1)
            time.sleep(1)
            self.d(resourceId='com.tencent.mm:id/fp', text='完成').click(timeout=1)

has_join_tag_group 方法用于判断好友是否已经被打上某个标签,比如“清粉-被删除”。根据返回值,程序决定是否为好友添加新标签。

针对不同的好友状态进行后续的操作

    def when_has_deleted(self):
        """
        如果当前好友已经将自己删除时
        :return:
        """
        self.d(resourceId='com.tencent.mm:id/mm_alert_ok_btn', text='我知道了').click_exists(timeout=3)

        # 1、退出【输入法】页面
        # self.d.press("back")
        # time.sleep(1)

        # 1、退出转账页面
        self.d.press("back")
        time.sleep(1)

        # 2、退出【红包、转账、语音输入、我的收藏……】页面
        self.d.press("back")
        time.sleep(1)

        # 3、退出聊天页面
        self.d.press("back")
        time.sleep(1)

        tag_status = self.has_join_tag_group(self.TAG_HAS_DELETED)
        if tag_status != self.TAG_HAS_JOIN:
            self.join_tag_group(self.TAG_HAS_DELETED)

    def when_has_black(self):
        """
        如果当前好友已经将自己拉黑时
        :return:
        """
        self.d(resourceId='com.tencent.mm:id/mm_alert_ok_btn', text='我知道了').click_exists(timeout=3)

        # # 1、退出【输入法】页面
        # self.d.press("back")
        # time.sleep(1)

        # 2、退出转账页面
        self.d.press("back")
        time.sleep(1)

        # 3、退出【红包、转账、语音输入、我的收藏……】页面
        self.d.press("back")
        time.sleep(1)

        # 4、退出聊天页面
        self.d.press("back")
        time.sleep(1)

        tag_status = self.has_join_tag_group(self.TAG_HAS_BLACK)
        if tag_status != self.TAG_HAS_JOIN:
            self.join_tag_group(self.TAG_HAS_BLACK)

    def when_account_problem(self):
        """
        如果当前好友的账号出现问题时
        :return:
        """
        self.d(resourceId='com.tencent.mm:id/mm_alert_ok_btn', text='我知道了').click_exists(timeout=3)

        # # 1、退出【输入法】页面
        # self.d.press("back")
        # time.sleep(1)

        # 2、退出转账页面
        self.d.press("back")
        time.sleep(1)

        # 3、退出【红包、转账、语音输入、我的收藏……】页面
        self.d.press("back")
        time.sleep(1)

        # 4、退出聊天页面
        self.d.press("back")
        time.sleep(1)

        tag_status = self.has_join_tag_group(self.TAG_ACCOUNT_PROBLEM)
        if tag_status != self.TAG_HAS_JOIN:
            self.join_tag_group(self.TAG_ACCOUNT_PROBLEM)

    def when_normal(self):
        """
        如果当前好友是正常状态时
        :return:
        """
        # 1、退出【输入支付密码】页面
        self.d.press("back")
        time.sleep(1)

        # 2、退出【输入法】页面
        self.d.press("back")
        time.sleep(1)

        # 3、退出转账页面
        self.d.press("back")
        time.sleep(1)

        # 4、退出【红包、转账、语音输入、我的收藏……】页面
        self.d.press("back")
        time.sleep(1)

        # 5、退出聊天页面
        self.d.press("back")
        time.sleep(1)

当我们判断清楚了每一位好友的状态之后,我们还需要退回到通讯录页面,方便继续检测下一位好友。但是极有可能每一个状态返回到通讯录中的步骤可能不一样,因此,我们就最好是根据不同的状态来分别处理。

接下来就是最重要的步骤了,通过遍历通讯录中的每一个好友,来检测每一位好友的状态如何。

循环检查每个好友

    def check_every_friend(self):
        run_status = 'doing'
        time.sleep(3)
        elems = self.d(resourceId='com.tencent.mm:id/kbq')

        for elem in elems:
            print()

            time.sleep(1)
            friend_nickname = elem.get_text(timeout=10)
            # 点击进入好友详情页面
            print(f'进入好友详情页面 --> {friend_nickname}')
            # 判断是否需要忽略检测
            if friend_nickname in self.ignore_wx_code:
                print(f"可以直接忽略检测【{friend_nickname}】")
                continue

            elem.click(timeout=5)

            # 获取好友个人信息
            personal_info = self.get_personal_info()

            # 判断是否需要忽略检测
            if personal_info['wx_code'] in self.ignore_wx_code or personal_info['nickname'] in self.ignore_wx_code:
                print(f"忽略检测【{personal_info['nickname']}】【{personal_info['wx_code']}】")
                self.d.press("back")
                continue

            # 判断当前好友是否已经被检测过了
            if personal_info['wx_code'] in self.friends_has_checked:
                print(f"已经被检测过了,跳过检测【{personal_info['nickname']}】【{personal_info['wx_code']}】")
                self.d.press("back")
                continue

            # 判断当前好友的状态
            status = self.judge_friend_status()
            if status == self.FRIEND_STATUS_HAS_DELETED:
                self.when_has_deleted()
            elif status == self.FRIEND_STATUS_HAS_BLACK:
                self.when_has_black()
            elif status == self.FRIEND_STATUS_ACCOUNT_PROBLEM:
                self.when_account_problem()
            elif status == self.FRIEND_STATUS_NORMAL:
                self.when_normal()
            else:
                print(f'当前好友状态未知 {status}')
                exit()

            # 将当前好友的【状态】和【个人信息】数据进行合并
            personal_info['status'] = status
            print(personal_info)
            # 存储当前好友的信息
            write_content_to_file('./friends_info.log', personal_info)

            # 记录所有被检测好友的信息
            self.friends_list.append(personal_info)
            # 记录已经被检测的好友信息
            self.friends_has_checked[personal_info['wx_code']] = personal_info

            # 判断是否已经检查到最后一个好友
            if personal_info['wx_code'] == self.last_friend_wx_code:
                print('已经检查到最后一个好友')
                run_status = 'done'
                break

            time.sleep(1)
            # 退回到通讯录列表页面(重要!!!)
            self.d.press("back")

        return run_status

    def all_friends_check(self):
        """
        开始检查所有好友
        :param self:
        :return:
        """
        # 检查是否有设置最后一个好友的微信号
        if self.last_friend_wx_code == '':
            print('请先设置最后一个好友的微信号')
            return

        # 至少将自己的微信号加入到忽略检测列表中(因为自己不能给自己转账)
        if len(self.ignore_wx_code) == 0:
            print('至少将自己的微信号加入到忽略检测列表中,否则会发生报错')
            return

        # 根据设定的最大页数,循环对通讯录中的每一个好友进行检查
        i = 0
        while True:
            i += 1
            print(f"这是第 {i} 次翻页")
            if i >= self.max_page_get_friend_list:
                break

            run_status = self.check_every_friend()
            if run_status == 'done':
                break

            time.sleep(1)
            # 一页检查完了之后,向上滑动
            # self.d.swipe(100, 1000, 100, 500)
            self.d.swipe_ext("up", scale=0.9)
            # 向上滑动之后,等待一会儿
            time.sleep(2)

        print('所有好友检查完毕')

check_every_friend 方法遍历好友列表,进入每个好友的详情页面,根据好友的状态进行相应的处理。如果好友状态符合删除、拉黑或账号问题,程序会为其打上对应标签。

让代码跑起来

核心代码已经写完了,剩下的步骤就比较简单了,让代码跑起来就行了

def write_content_to_file(file_path: str, content):
    """
    将内容写入文件
    :param file_path:
    :param content:
    :return:
    """
    content_json = json.dumps(content, ensure_ascii=False)
    with open(file_path, 'a', encoding='utf-8') as file_to_write:
        file_to_write.write(content_json + '\n')


if __name__ == '__main__':
    last_friend_wx_code = '123'

    # 需要被忽略检测的微信号或者微信昵称
    # 这里至少将自己的微信号加入到忽略检测列表中(因为自己不能给自己转账)
    # 并且也必须保留以下【微信团队】和【文件传输助手】
    ignore_wx_code = ['微信团队', '文件传输助手']

    max_page_get_friend_list = 8

    wx_clean = WXCleanFriends(last_friend_wx_code, ignore_wx_code, max_page_get_friend_list)

    # wx_clean.test_run()
    # exit()

    # 开启调试模式
    wx_clean.enable_debug()

    # 打开微信
    # wx_clean.weixin_start()
    # 点击【通讯录】
    # wx_clean.open_contacts()
    # 让通讯录页面加载完毕
    # time.sleep(3)

    # 开始检查所有好友
    wx_clean.all_friends_check()

    friends_list = wx_clean.get_friends_list()
    write_content_to_file('./friends_list.json', friends_list)
    print(friends_list)

总结

这款微信清理僵尸粉工具使用 Python 和 uiautomator2 库通过自动化方式帮助我们批量清理微信好友中的不活跃或无效好友。

通过检查好友的状态并为其打上标签,工具不仅提高了清理效率,也避免了人工逐个操作的繁琐。对于开发者而言,这个项目展示了如何结合 Python 与自动化工具进行高效的设备操作和应用管理。

如果你也有类似的需求,不妨也玩一玩……

这篇文章只是将不同状态的好友打上了标签,下一篇文章详解自动化删除指定标签中的所有好友,可以观望一下。😄

相关文章
|
7月前
|
人工智能 安全 IDE
【AI帮我写代码,上班摸鱼不是梦】手摸手图解CodeWhisperer的安装使用
除了借助ChatGPT通过问答的方式生成代码,也可以通过IDEA插件在写代码是直接帮助我们生成代码。 目前,IDEA插件有CodeGeeX、CodeWhisperer、Copilot。其中,CodeGeeX和CodeWhisperer是完全免费的,Copilot是收费的,每月10美元。 下面我们来了解CodeWhisperer的安装和使用,如果你还想了解其他的可以在评论告诉我。
218 4
|
移动开发 程序员 编译器
三分钟创建一个新应用,ivx的神奇之处【PPT式程序开发】
IVX是一门人人都能快速掌握的可视化编程语言
111 0
|
4月前
|
数据采集 存储 JSON
推荐3款自动爬虫神器,再也不用手撸代码了
推荐3款自动爬虫神器,再也不用手撸代码了
|
4月前
|
移动开发 JavaScript 前端开发
【绝技揭秘】从零到英雄:解锁UniApp H5项目中的二维码生成与扫描秘籍,让你的应用瞬间变身扫码达人!
【8月更文挑战第20天】二维码在移动应用中无处不在。本文详述了在UniApp H5项目中实现二维码生成与扫描的方法。通过对比插件`uni-app-qrcode`和JavaScript库`qrcode-generator`生成二维码的方式,以及使用插件`@juggle/resize-observer`和HTML5的MediaDevices API进行扫描的技术方案,帮助开发者挑选最佳实践。无论是插件的便捷性还是原生JavaScript的灵活性,都能满足不同项目需求。
128 0
|
6月前
|
JSON 小程序 JavaScript
技术心得记录:小爱童鞋@你,一起来撸个小程序吧
技术心得记录:小爱童鞋@你,一起来撸个小程序吧
53 0
[完结]微课设计零基础入门 | 8.微课的录制和后期的剪辑
为了让大家看到如何去剪录制过程中的错误,我在视频中录制“查字典”微课的时候,多个地方发生了错误,但我生成教程视频的时候都保留了原样,确保大家能看到录制过程中错误的产生和后期的纠正。
110 0
|
数据可视化 搜索推荐 程序员
丝滑!用了这款开发工具,我成了整个公司代码写得最秀的码农
丝滑!用了这款开发工具,我成了整个公司代码写得最秀的码农
|
前端开发 Java 数据库
SpringBoot日记本系统全程直播01:先把框架搞起来撒~~
SpringBoot日记本系统全程直播01:先把框架搞起来撒~~
131 0
|
Java 网络安全 Maven
30 个 IDEA 常用小技巧,应有尽有,让你的撸码效率直接起飞...(1)
30 个 IDEA 常用小技巧,应有尽有,让你的撸码效率直接起飞...
178 0
30 个 IDEA 常用小技巧,应有尽有,让你的撸码效率直接起飞...(1)
|
IDE Java Maven
30 个 IDEA 常用小技巧,应有尽有,让你的撸码效率直接起飞...(2)
30 个 IDEA 常用小技巧,应有尽有,让你的撸码效率直接起飞...
173 0
30 个 IDEA 常用小技巧,应有尽有,让你的撸码效率直接起飞...(2)