Python+ADB实现Android手机QQ自动点赞

2023-05-16

1、 前言

前段时间看了些爬虫的知识,然后又看到selenium,Appium,在Appium环境设置过程中,意外地看到这个帖子adb命令模拟按键事件 KeyCode,然后结合相关搜索结果,完成了“QQ点赞这个想法”这个想法。

2、  环境

Windows 10、Python2.7.13、Android SDK、Android手机QQ 7.0.0.3135

3、 分析

3.1     相关命令

3.1.1adb shell input命令

Usage: input [<source>] <command> [<arg>...]

The sources are:
      keyboard
      mouse
      joystick
      touchnavigation
      touchpad
      trackball
      dpad
      stylus
      gamepad
      touchscreen

The commands and default sources are:
      text <string> (Default: touchscreen)
      keyevent [--longpress] <key code number or name> ... (Default: keyboard)
      tap <x> <y> (Default: touchscreen)
      swipe <x1> <y1> <x2> <y2> [duration(ms)] (Default: touchscreen)
      press (Default: trackball)
      roll <dx> <dy> (Default: trackball)

程序中用了其中的如下命令:

0、 adb shell input keyevent keycode命令,用于模拟在Android手机上按的一些特殊键(更多值还是看这个链接adb命令模拟按键事件 KeyCode),例如:

keycode为KEYCODE_BACK,执行命令相当于按了返回键;

keycode为KEYCODE_DPAD_UP或KEYCODE_DPAD_DOWN用于模拟上下键,按上下键可使屏幕上的控件出现被选中的背景色(就是按下分组名时控件背景闪现的灰色);

keycode为KEYCODE_MOVE_HOME时,可回到屏幕顶端(如在QQ空间向下翻了之后,连续以这个值为keycode,执行两次该命令,就可回到顶部);在联系人列表中,若没有控件被选中(即有灰色背景色),以KEYCODE_MOVE_HOME为keycode值执行命令,就可以让刚才选中过的控件被选中,再次执行则会选中列表中最顶端控件,QQ 7.0中,则会选中“特别关心”这个控件。

1、 adb shell input tap <x> <y>,该命令点击屏幕指定的坐标处,本程序主要用于点开联系人列表、点击列表中的好友进入个人资料卡界面、点击点赞图标。

2、 adb shell input swipe <x1> <y1> <x2> <y2> [duration(ms)],用于模拟在两个点之间滑动,最后一个参数是毫秒为单位的持续时间。


3.1.2 adb shell uiautomator dump [path]filename.xml命令

(来源:通过adb获取安卓应用屏幕所有控件信息)

查看帮助:
C:\Users\Dragon>adb shell uiautomator
Usage: uiautomator <subcommand> [options]

Available subcommands:

help: displays help message

runtest: executes UI automation tests
    runtest <class spec> [options]
    <class spec>: <JARS> < -c <CLASSES> | -e class <CLASSES> >
      <JARS>: a list of jar files containing test classes and dependencies. If
        the path is relative, it's assumed to be under /data/local/tmp. Use
        absolute path if the file is elsewhere. Multiple files can be
        specified, separated by space.
      <CLASSES>: a list of test class names to run, separated by comma. To
        a single method, use TestClass#testMethod format. The -e or -c option
        may be repeated. This option is not required and if not provided then
        all the tests in provided jars will be run automatically.
    options:
      --nohup: trap SIG_HUP, so test won't terminate even if parent process
               is terminated, e.g. USB is disconnected.
      -e debug [true|false]: wait for debugger to connect before starting.
      -e runner [CLASS]: use specified test runner class instead. If
        unspecified, framework default runner will be used.
      -e <NAME> <VALUE>: other name-value pairs to be passed to test classes.
        May be repeated.
      -e outputFormat simple | -s: enabled less verbose JUnit style output.

dump: creates an XML dump of current UI hierarchy
    dump [--verbose][file]
      [--compressed]: dumps compressed layout information.
      [file]: the location where the dumped XML should be stored, default is
      /sdcard/window_dump.xml

events: prints out accessibility events until terminated
该命令会将当前的Activity信息以XML文件的形式存在手机中,XML文件中存放了各标签的一些属性,如本程序中用到的class、resource-id、checked、selected、bounds属性,其中bounds属性的值形式为[x1,y1][x2,y2],[x1,y1]为控件的左上角坐标,[x2,y2]为控件的右下角坐标。本程序就是利用对得到的XML文件的操作,使用正则表达式解析出控件坐标,从而使用上面提到的adb shell input命令模拟点击屏幕等对手机进行操作(本程序的点击操作使用的坐标都是计算的控件的中心坐标)。

3.1.3 其它相关命令

0、adb shell wm size命令,输出的字符中,包含了屏幕分辨率,也可用正则表达式解析出来,从而根据屏幕分辨率使用比例进行模拟滑动等操作。

1、获取当前与用户交互的Activity:通过adb shell命令查看当前与用户交互的activity,也可从输出中解析出活动,可用于判断是否进入了QQ这个程序的指定界面。(本程序没添加该功能)

2、Android中的一个am命令,可用于启动程序,不过我的手机没root,测试了几下不成功。也没加这个功能。

3.2 程序流程图


3.3 一些问题的处理

0、正则表达式解析的模式字符串从哪里找?

程序是在Windows上运行,所以要先使用adb pull命令将手机中的XML文件复制到PC中,然后在ui automator viewer中找到想处理的控件,通过bounds属性值在XML文件中查找标签,然后分析控件标签的特征字符串,构建正则表达式。

(如果能使用am命令启动程序,或许还可以直接在手机上运行代码,而且文件也不用复制到PC中,执行的shell命令也是在手机中执行。只需一个Python环境如QPython即可)

1、 联系人界面,如何确定选中的控件?

XML的标签中有属性selected,对于选中的控件,其值为true。

2、分组控件的处理,联系人列表是否已经展开

通过uiautomator viewer查看分组控件属性如下:
分组列表控件及其子控件中XML代码:
<node … resource-id="com.tencent.mobileqq:id/group_item_layout" … selected="true" bounds="[0,509][1080,647]">
<node … resource-id="com.tencent.mobileqq:id/name" class="android.widget.CheckBox" … checked="false" … selected="true" bounds="[32,533][64,623]"/>
通过观察,第一个子控件即 CheckBox ,若分组展开,其 checked 属性值为 true ,所以可通过这个判断以决定是否展开该分组下联系人列表。
3、判断是否是最后一个好友
光标经过最后一个好友之后,会再向下移动,移出好友列表之外,此时通过正则表达式匹配选中的控件会返回None,通过这个可判断是否已经是最后一个好友。(但中间可能发生一些意外情况,所以使用了一个变量作为计数器,每遇到返回None,计数器减1,计数器为0后,程序退出)

4、判断光标是否超出了屏幕范围,而并非是最后一个好友这种情况。

这种情况也可能发生,当屏幕下方可视范围内显示的不是完整的好友控件时,可能光标会在屏幕外并继续向下移动,但是这时正则表达式匹配不到已选中的控件,所以返回None。其中一种方法是:最开始先点击屏幕下方的联系人,折叠所有好友列表,然后向上滑动屏幕,这使“好友、群、…”那一列位于界面上“联系人”标题所在的控件下方,这样的话,光标向下移动时,列表会自动向上移动,使选中的联系人控件在屏幕可见范围内。

然而也可能遇到一些特殊情况,使得运行过程中可能出现意外情况。

3.4 未处理好的问题

这种情况:


有的人使用了QQ厘米秀这个功能,而且,遮挡的位置不同,但只要这个厘米秀人物在点赞图标附近,就会点到这个厘米秀人物进入别的页面。本是打算进入个人资料卡后先向上滑动屏幕,但是滑动的少的话还是会点击到这个人物,滑动得多的话,有的人的点赞图标又滑动到屏幕外去了。本程序未对这种情况做完善处理。

4、源代码

(本程序必须手动让手机进入QQ程序,并且要借助USB数据线,有一些局限性)
# _*_ coding: utf-8 _*_
# @Time : 2017/5/10 22:57
# @Author : 0x3E6
# @File : android_qq_praise.py
import os
import re

class QQPraise():
    def __init__(self):
        self.screen_center_x=0
        self.screen_center_y=0
        self.fd=None
        self.contact_UI_content=None
        self.profile_crad_content=None
        self.pattern=None
        self.points=None
        self.x=0
        self.y=0
        self.num=0

    def entry_point(self):
        self.prepare()
        i=0
        while 1:
            type = self.find_type_of_selected_widget()
            if type == "friend_widget":
                self.parse_coordinate()
                os.system("adb shell input tap %s %s" % (self.x, self.y))
                self.praise_and_return()
            elif type == "group_widget":
                self.expand_group()
            else:
                i+=1
                if i==10:
                    break
            if self.cursor_out_of_screen():
                os.system("adb shell input keyevent KEYCODE_PAGE_DOWN")
            os.system("adb shell input keyevent KEYCODE_DPAD_DOWN")

    def prepare(self):
        # 先切换到QQ主界面的中间联系人列表界面
        self.load_layout_xml("contacts_list.xml",1)
        self.pattern = "bounds=\"\[(\d{1,4}),(\d{1,4})\]\[(\d{1,4}),(\d{1,4})\][^>]*><node[^>]*text=\"联系人\" resource-id=\"com\.tencent\.mobileqq:id/name\""
        contact_widget=self.parse_UI(self.contact_UI_content)
        if contact_widget:
            os.system("adb shell input tap %s %s" % (self.x, self.y))
        # 选择好友列表
        self.load_layout_xml("contacts_list.xml",1)
        points=re.search("<node[^>]*text=\"好友\"[^>]*bounds=\"\[(\d{1,4}),(\d{1,4})\]\[(\d{1,4}),(\d{1,4})\]",self.contact_UI_content).groups()

        x=int(points[0])+(int(points[2])-int(points[0]))/2
        y=int(points[1])+(int(points[3])-int(points[1]))/2
        os.system("adb shell input tap %s %s" % (x,y))
        # 折叠好友列表
        os.system("adb shell input tap %s %s" % (self.x,self.y))
        # 获取屏幕分辨率计算屏幕中心
        f=os.popen("adb shell wm size")
        screen_width,screen_height=re.search("(\d{3,4})x(\d{3,4})",f.read()).groups()
        center=(int(screen_width)/2,int(screen_height)/2)
        self.screen_center_x=center[0]
        self.screen_center_y=center[1]
        # 向上划一下,将“好友、群、...”那一行移动到最上面
        os.system("adb shell input swipe %s %s %s %s" % (center[0],center[1],center[0],0))
        # 发送KEYCODE_MOVE_HOME将光标定位到“特别关心”分组
        os.system("for /L %%i in (1,1,2) do adb shell input keyevent KEYCODE_MOVE_HOME")

    def load_layout_xml(self, xml_name,option):
        # os.system("adb shell uiautomator dump /storage/sdcard0/friend_profile_card.xml")
        os.system("adb shell uiautomator dump /storage/sdcard0/%s" % xml_name)
        os.system("adb pull /storage/sdcard0/%s ./%s" % (xml_name, xml_name))
        self.fd = open(xml_name, "r")
        if option==1:
            self.contact_UI_content = self.fd.read()
        elif option==2:
            self.profile_crad_content=self.fd.read()
        self.fd.close()

    def parse_UI(self,content):
        result=re.search(self.pattern,content)
        if result:
            if len(result.groups())==5:
                self.points=result.groups()[1:]
                return result.groups()[0]
            elif len(result.groups())==4:
                self.points=result.groups()
                self.parse_coordinate()
                return True
            elif len(result.groups())==1:
                return result.groups()[0]
        else:
            return False

    def parse_coordinate(self):
        min_x = int(self.points[0])
        min_y = int(self.points[1])
        max_x = int(self.points[2])
        max_y = int(self.points[3])
        self.x = min_x + (max_x - min_x) / 2
        self.y = min_y + (max_y - min_y) / 2

    def find_type_of_selected_widget(self):
        self.load_layout_xml("contacts_list.xml",1)
        self.pattern = "<node[^>]*(id/group|LinearLayout)[^>]*selected=\"true\"[^>]*bounds=\"\[(\d{1,4}),(\d{1,4})\]\[(\d{1,4}),(\d{1,4})\]\"[^>]*>"
        contact_widget=self.parse_UI(self.contact_UI_content)
        if contact_widget:
            if "LinearLayout" == contact_widget:
                # print "好友控件", "坐标", type.groups()[1:]
                return "friend_widget"
            elif "id/group" == contact_widget:
                # print "分组控件", "坐标", type.groups()[1:]
                return "group_widget"
        else:
            return None

    def expand_group(self):
        coordinate = (int(self.points[0]), int(self.points[1]), int(self.points[2]), int(self.points[3]))
        self.pattern = "\[%s,%s\]\[%s,%s\]\"><node[^>]*checked=\"([^\"]*)\"" % coordinate
        checked = self.parse_UI(self.contact_UI_content)
        if checked == 'false':
            self.parse_coordinate()
            os.system("adb shell input tap %s %s" % (self.x, self.y))

    def praise_and_return(self):
        self.num+=1
        # 若有的好友资料卡中赞的位置被厘米秀挡住,需要取消下面这一行的注释,但这并不能解决所有问题
        os.system("adb shell input swipe %s %s %s %s" % (self.screen_center_x,self.screen_center_y,self.screen_center_x,self.screen_center_y*2/3))
        self.load_layout_xml("friend_profile_card.xml",2)
        # 找点赞位置
        self.pattern="<node [^<]*点击可赞[^>]* bounds=\"\[(\d{1,4}),(\d{1,4})\]\[(\d{1,4}),(\d{1,4})\].*"
        result=self.parse_UI(self.profile_crad_content)
        if result:
            os.system("FOR /L %%v IN (1,1,10) DO adb shell input tap %s %s" % (self.x, self.y))
            os.system("adb shell input keyevent KEYCODE_BACK && adb shell input keyevent KEYCODE_MOVE_HOME")

    def cursor_out_of_screen(self):
        self.pattern = "<node[^>]*selected=\"true\"[^>]*>[^<]*(</node>){6}"
        is_out = re.search(self.pattern, self.contact_UI_content)
        if is_out:
            return True
        else:
            return False

def main():
    praiser=QQPraise()
    praiser.entry_point()

if __name__ == "__main__":
    main()


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python+ADB实现Android手机QQ自动点赞 的相关文章

  • Python 3:将字符串转换为变量[重复]

    这个问题在这里已经有答案了 我正在从 txt 文件读取文本 并且需要使用我读取的数据之一作为类实例的变量 class Sports def init self players 0 location name self players pla
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • Mipmap 与可绘制文件夹[重复]

    这个问题在这里已经有答案了 我正在使用 Android Studio 1 1 Preview 1 我注意到 当我创建一个新项目时 我得到以下层次结构 不同 DPI 的 Mipmap 文件夹 不再有不同 DPI 的可绘制文件夹 我应该将所有资
  • 导入错误:没有名为flask.ext.login的模块

    我的flask login 模块有问题 我已经成功安装了flask login模块 另外 从命令提示符我可以轻松运行此脚本 不会出现错误 Python 2 7 r27 82525 Jul 4 2010 07 43 08 MSC v 1500
  • 无法导入 langchain.agents.load_tools

    我正在尝试使用 LangChain Agents 但无法导入 load tools 版本 langchain 0 0 27 我尝试过这些 from langchain agents import initialize agent from
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • 我应该释放或重置 MediaPlayer 吗?

    我有自己的自定义适配器类 称为 WordAdapter 并且我正在使用媒体播放器 名为pronounce WordAdapter 类中的全局变量 我有不同的活动 其中每个列表项都有线性布局 名为linearLayout 我正在设置onCli
  • python的shutil.move()在linux上是原子的吗?

    我想知道python的shutil move在linux上是否是原子的 如果源文件和目标文件位于两个不同的分区上 行为是否不同 或者与它们存在于同一分区上时的行为相同吗 我更关心的是如果源文件和目标文件位于同一分区上 shutil move
  • Android Studio 无法识别 Mac/Linux 上的 OnePlus2

    我的 Android Studio 1 3 2 无法识别我的手机 一加二号 我有 Mac OS x Yosemite 10 10 5 和最新的 Android SDK 更新1 我的Mac上安装的文件传输软件 Android File Tra
  • Django 视图中的“请求”是什么

    在 Django 第一个应用程序的 Django 教程中 我们有 from django http import HttpResponse def index request return HttpResponse Hello world
  • 您使用什么物理 Android 设备进行测试?

    有什么好的推荐用于测试目的的物理 Android 设备吗 我正在苹果阵营寻找像 iPod touch 这样的设备 可以帮助 iOS 开发人员测试他们的东西 我知道有 Nexus One 但那东西相当昂贵 而且我并不真正关心手机的东西 而是可
  • Python GTK+ 画布

    我目前正在通过 PyGobject 学习 GTK 需要画布之类的东西 我已经搜索了文档 发现两个小部件似乎可以完成这项工作 GtkDrawingArea 和 GtkLayout 我需要一些基本函数 如 fillrect 或 drawline
  • PySpark groupByKey 返回 pyspark.resultiterable.ResultIterable

    我试图找出为什么我的 groupByKey 返回以下内容 0
  • 带有 LSTM 的 GridSearchCV/RandomizedSearchCV

    我一直在尝试通过 RandomizedSearchCV 调整 LSTM 的超参数 我的代码如下 X train X train reshape X train shape 0 1 X train shape 1 X test X test
  • 如何以正确的方式为独立的Python应用程序制作setup.py?

    我读过几个类似的主题 但还没有成功 我觉得我错过或误解了一些基本的事情 这就是我失败的原因 我有一个用 python 编写的 应用程序 我想在标准 setup py 的帮助下进行部署 由于功能复杂 它由不同的 python 模块组成 但单独
  • 通过电子邮件发送文本文件附件

    我正在尝试附加一个文本文件以便通过电子邮件发送 但每当我打开电子邮件应用程序时 它都会说该文件不存在 请帮助 Intent i new Intent Intent ACTION SEND i setType text plain i put
  • Firebase Firestore:获取文档的生成 ID (Python)

    我可以创建一个新文档 带有自动生成的 ID 并存储对其的引用 如下所示 my data key value doc ref db collection u campaigns add my data 我可以像这样访问数据本身 print d
  • 根据 Pandas 中的列表选择数据框行的子集

    我有一个数据框df1并列出x In 22 import pandas as pd In 23 df1 pd DataFrame C range 5 B range 10 20 2 A list abcde In 24 df1 Out 24
  • 发布的 Android apk 出现错误“包文件未正确签名”

    我最近将我的应用程序上传到 Android 市场 但是由于错误 下载时它拒绝运行 包文件未正确签名 我首先使用 eclipse 发布了数据包 右键单击导出 创建密钥库然后发布 但它拒绝工作 然后我下载了 keytool 和 jarsigne

随机推荐

  • FreeRTOS --(4)任务管理之启动调度器

    目录 1 vTaskStartScheduler 2 xPortStartScheduler 3 vPortSetupTimerInterrupt 4 prvStartFirstTask 5 vPortSVCHandler 在使用 Free
  • FreeRTOS --(7)任务管理之任务切换

    现在创建任务 xff08 xTaskCreate xff09 启动调度器 xff08 vTaskStartScheduler xff09 xff0c 任务控制 xTaskDelay xff0c 以及Tick 中断 xff08 xPortSy
  • Spring Aop到底有什么用处?

    假如没有aop xff0c 在做日志处理的时候 xff0c 我们会在每个方法中添加日志处理 xff0c 比如 但大多数的日子处理代码是相同的 xff0c 为了实现代码复用 xff0c 我们可能把日志处理抽离成一个新的方法 但是这样我们仍然必
  • 获取对象自身的属性

    问题 找出对象 obj 不在原型链上的属性 注意这题测试例子的冒号后面也有一个空格 1 返回数组 xff0c 格式为 key value 2 结果数组不要求顺序 答案 Object keys 方法 xff08 156 ms xff09 返回
  • 重启linux后无法ssh登录

    博客搬运自我的个人博客 chantAria的博客 精力有限 新博客我会同步到CSDN 但博客内容的更新只会出现在个人博客 欢迎大家来玩耍哦 重启llinux后无法ssh登录的情况很多 其中一种情况是在之前update的时候产生了一个坏的内核
  • 使用FFmpeg将视频编码格式转化为H264编码

    背景介绍 xff1a web开发中涉及到视频播放的前端一般会使用h5的video标签对后端提供的视频文件url直接加载进行播放 xff0c 虽然视频文件后缀都是mp4 xff0c 但并非所有视频文件的编码格式都支持用video播放 xff0
  • Cause: org.xml.sax.SAXParseException; lineNumber: 5; columnNumber: 26; 1 字节的 UTF-8 序列的字节 1 无效。

    报错为 xff1a Cause org xml sax SAXParseException lineNumber 5 columnNumber 26 1 字节的 UTF 8 序列的字节 1 无效 是你的xml文件里面的 设置成了默认的UTF
  • Centos7 java服务开机自启动

    1 在 etc systemd system 目录下 新建脚本 cd span class token operator span usr span class token operator span lib span class toke
  • 我使用过的linux命令之strings

    strings命令用于输出文件中可打印的字符串 不论文件是普通文本 xff0c 还是可执行文件 xff0c 任何文件都可以 最常用的选项 xff1a a 扫描整个文件的任何段 xff0c 这是strings的默认行为 xff0c 但是这种默
  • HashMap的工作原理

    HashMap主要是用来处理键值对数据 xff0c 随着JDK版本的更新 xff0c JDK1 8对HashMap的底层也做了一些优化 xff0c HashMap是基于哈希表对Map接口的实现类 xff0c 它的特点是访问数据速度快 xff
  • 如何配置终端代理apt 代理

    1 临时用代理 xff0c 直接在终端里export代理 export http proxy 61 http 127 0 0 1 7890 export https proxy 61 http 127 0 0 1 7890 2 在 etc
  • ssh修改连接端口,以及修改端口之后连接不上的问题

    SSh服务配置文件路径一般都是在 etc ssh这个目录下面 sshd config 这个文件 使用VI vim编辑器 xff0c 打开sshd config这个文件 xff0c 搜索找到 port字段 去掉 xff0c 修改port 后面
  • FreeRTOS原理剖析:任务的创建

    1 任务创建API函数 任务的最基本功能是任务管理 xff0c 任务管理中最基本操作是任务的创建和删除 对于任务的创建和删除 xff0c 由于篇幅有点长 xff0c 分两篇分别讲解 在FreeRTOS中任务的创建函数如下 xff1a 函数描
  • @xmlAttribute等注解它的用处?

    用的是jdk自带的javax xml bind JAXBContext将对象和xml字符串进行相互转换 如果对要生成的 xml 格式有点些许的限制 xff0c 就会对生成xml的对象就需要进行些许控制 xff0c 控制对象的一个最可行的办法
  • C/C++ 分支预测(likely unlikely)

    看一些代码时 xff0c 会遇到likely unlikely 查了查网上的资料 xff0c 结合自己的理解记录一下 1 一些概念 指令周期 是指执行一条指令所需要的时间 xff0c 一般由若干个机器周期组成 xff0c 是从取指令 分析指
  • Vnc viewer与windows之间的复制粘贴

    用VNC连接到Linux之后 xff0c 最纠结的问题就是无法复制粘贴 其实很简单 xff0c 在Linux里面 xff0c 打开一个终端 xff0c 然后输入命令 xff1a vncconfig 之后 xff0c 会弹出一个窗口 不要关闭
  • Android studio 添加多语言支持

    环境 xff1a Android studio 3 2 执行步骤 xff1a 一 生成对应语言文件夹 选中你的工程 gt res gt 右键点击new gt 选中Android resource directory Available qu
  • VNC 远程环境搭建教程

    最近因项目需要使用到 VNC 远程工具 xff0c 因此记录使用过程 一 在 VNC 官网下载 VNC 服务端和客户端安装包 进入下载页面 二 注册 VNC 官网账号 三 在本地安装 VNC 客户端 xff0c 被远程电脑安装 VNC 服务
  • Ubuntu桌面出现Accept clipboard from viewers,Send clipboard to viewers,Send primary selection to vi等三行错误时

    如上图的错误时 1 输入以下神秘代码 sudo apt get install gnome core2 重启vnc服务3 若还不行 xff0c 则修改xstartup脚本 方法见下链接第五部分 修改xstartup
  • Python+ADB实现Android手机QQ自动点赞

    1 前言 前段时间看了些爬虫的知识 xff0c 然后又看到selenium xff0c Appium xff0c 在Appium环境设置过程中 xff0c 意外地看到这个帖子adb命令模拟按键事件 KeyCode xff0c 然后结合相关搜