• Appium自动微信读书打卡


    1.需求分析

    1.1需求

     本研究目的是实现在手机上自动完成读书打卡功能。

    1.2分析

    实现微信读书打卡项目,分为两部分,第一部分是实现微信读书,第二部分是实现打卡。微信读书部分需要先找到需要阅读的书籍,然后滑动书籍,最后对获取书籍右下角的页码。打卡部分需要先搜索到微信群聊,然后复制页码信息,最后把页码发送到指定的群里。

    2.设计

    从需求分析中,可总结出需要设计实现以下三种功能
    功能1需要能够连接并能够启动移动端app的工具帮助实现自动化
    功能2微信读书识别打卡页码内容
    功能3打卡页码文本内容发送到微信打卡群

    功能1的设计实现,可采用appium框架工具实现app自动化;

    功能2的设计实现,可归纳为以下几点
    1)启动微信读书app。在app中找到需要打卡的书籍,定时翻页查看书籍,记录书籍开始阅读到结束阅读时的起止页码。
    其中找到需要阅读的书籍以及翻页可借助appium实现,对于记录页码,需要做出讨论。如果页码内容属于文本内容,通过appium定位工具可读取到页码;如果页码部分属于非文本内容,则采用生成页码部分图片,然后图片内容识别文本技术识别页码内容。(经过实践,app中页码部分为非文本内容,页码图片使用appium框架截图API生成,页码图片内容识别技术使用Tesseract-OCR软件识别),以上描述设计实现读取打卡的页码功能思路。
    2)打卡页码发送到微信群。启动并登录微信,找到需要打卡的群聊,将打卡内容(微信读书已阅读到的页码)通过群聊输入框发送至微信群,完成打卡功能

    3.实现

    项目分为微信读书和打卡两部分实现。

    3.1微信读书

    3.1.1说明

    先打开微信读书,点击书架[书架ID]按钮,找到指定的书籍[书籍ID]点击,设置固定时间间隔向左滑动屏幕,设置一段时间读取书籍右下角的页码。

    3.1.2步骤

    1)找到书籍

    点击书架[书架ID]按钮,找到指定的书籍[书籍ID]点击。

           // 定位书架位置
            String book_id = "com.tencent.weread:id/rx";
            driver.findElementById(book_id).click();
            Thread.sleep(1000);
            // waiTime(500, driver);
    
            // 点开所需要的书籍
            String book_xpath = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/androidx.viewpager.widget.ViewPager/android.widget.FrameLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout/android.widget.FrameLayout/androidx.recyclerview.widget.RecyclerView/android.widget.RelativeLayout[8]/android.widget.RelativeLayout/android.view.View[2]";
            driver.findElementByXPath(book_xpath).click();

    2)滑动书籍

        //向左滑动
        public static void swipeToLeft(AndroidDriver driver) {
            int width = driver.manage().window().getSize().width;// 获取当前屏幕的宽度
            int height = driver.manage().window().getSize().height;// 获取当前屏幕的高
            TouchAction touchAction = new TouchAction(driver);
            //new一个TouchAction对象,调用其按压press()方法,输入坐标点,moveTo移动到下一个坐标点,之后调用release()和perform()方法执行
            PointOption startOption = PointOption.point(width * 4 / 5, height / 2);
            PointOption endOption = PointOption.point(width / 5, height / 2);        //向左边滑动100ms
            WaitOptions waitOption = WaitOptions.waitOptions(Duration.ofMillis(100));// 设置动作持续时间:按压一秒
            touchAction.press(startOption).waitAction(waitOption).moveTo(endOption).release().perform();// 按压一秒——移动——松开释放
    
        }

    3)定时

    这里定时是指两个定时,第一个是阅读的书籍应该每隔多长时间滑动一次,第二个定时是每次固定多长时间结束阅读。我测试了我大概阅读一页的速度是40s(我手机中的微信读书的字体设置的是20),所以我设置每隔40s滑动一次屏幕。设置每隔40s滑动一次屏幕,一共滑动30页。

           // 滑动书籍
            int k = 0;
            while (k < 1) {
                Thread.sleep(24000);
                swipeToLeft(driver);
                k++;
            }

    4)截图

        /**
         * 截图
         */
        public static String captureApp(AndroidDriver driver) {
            System.out.println("开始截图");
            // 截图名称
            String screenshotName = getCurrentDateTime() + "wechat_book.png";
            String filePath = SCREENSHOT_PATH + File.separator + screenshotName;
            // 截图目录
            File screenshotFile = new File(SCREENSHOT_PATH);
            // 若文件夹不存在就创建该文件夹
            if (!screenshotFile.exists() && !screenshotFile.isDirectory()) {
                screenshotFile.mkdirs();
            }
    
            try {
                // 截图操作
                File sourceFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
                // 截图存储
                FileUtils.copyFile(sourceFile, new File(filePath));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("截图操作异常!");
            }
            System.out.println("截图结束");
            return filePath;
        }

    5)识别页码

    public static void getSubImg(String soursePicPath, String targetPath) {
            File sourcePic = new File(soursePicPath);
            try {
                BufferedImage pic1 = ImageIO.read(sourcePic);
                int width = pic1.getWidth();
                int height = pic1.getHeight();
                // 参数依次为,截取起点的x坐标,y坐标,截取宽度,截取高度
                BufferedImage pic2 = pic1.getSubimage(width / 9 * 7, height / 16 * 15, width / 9 * 2, height / 16 * 1);
                // 将截取的子图另行存储
                File desImage = new File(targetPath);
                ImageIO.write(pic2, "png", desImage);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }

    3.1.3结果

    实现微信读书并获取书籍页码。

    3.2打卡

    3.2.1说明

    打开微信,找到搜索按钮的ID,找到搜索框第一条结果,取文本框ID并输入文字,点击确定按钮,即找到确定按钮ID。

    3.2.2步骤

    1)向微信发送消息

    设置Appium可以输入中文

    //设置appium可以输入中文
            capabilities.setCapability("unicodeKeyboard", "true");

    2)打开微信

    //    获取微信driver
        public static AndroidDriver getWechatDriver() throws Exception {
            DesiredCapabilities capabilities = new DesiredCapabilities();
            // 模拟器类型
            // capabilities.setCapability("deviceName", "Android Emulator");
            capabilities.setCapability("deviceName", "device");
            // 自动化测试引擎
            capabilities.setCapability("automationName", "Appium");
            // 手机操作系统Android
            capabilities.setCapability("platformName", "Android");
            // 手机操作系统版本号
            capabilities.setCapability("platformVersion", "7.1.2");
            // app包名
            capabilities.setCapability("appPackage", "com.tencent.mm");
            // app中启动的 Activity名称
            capabilities.setCapability("appActivity", ".ui.LauncherUI");
            capabilities.setCapability("automationName", "uiautomator2");
            // noReset设置
            capabilities.setCapability("noReset", "true");
            // 设置appium可以输入中文
            capabilities.setCapability("unicodeKeyboard", "true");
            AndroidDriver driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
            return driver;
        }

    3)完成打卡

    public static void showTime(String pageNum) throws Exception {
    //        获得微信driver
            AndroidDriver driver = getWechatDriver();
    //        微信首页启动大概6s
            Thread.sleep(10000);
            // 打开微信kyt
    //        String wx_xpath = "//android.widget.TextView[@content-desc=\"微信\"]";
    //        driver.findElementByXPath(wx_xpath).click();
    //        Thread.sleep(1000);
            // 找到搜索按钮的ID
            String wx_find = "com.tencent.mm:id/he6";
            driver.findElementById(wx_find).click();
            Thread.sleep(1000);
            // 取文本框ID并输入文字
            String wx_group = "com.tencent.mm:id/bxz";
            driver.findElementById(wx_group).sendKeys("小窝窝");
            Thread.sleep(1000);
            // 找到搜索框第一条结果
            String group_loaction = "com.tencent.mm:id/ir3";
            driver.findElementById(group_loaction).click();
            Thread.sleep(1000);
            // 输入读书的名称和页码
            String sendmassage = "com.tencent.mm:id/auj";
            driver.findElementById(sendmassage).sendKeys("名人名言书屏" + pageNum);
            Thread.sleep(1000);
            // 点击确定按钮,即找到确定按钮ID
            String sendbutton = "com.tencent.mm:id/ay5";
            driver.findElementById(sendbutton).click();
            driver.closeApp();
            driver.quit();
    
        }

    3.2.3实现

    实现效果如下图所示,微信读书在微信上打卡成功。

    4.断网测试

    把网断开进行测试,看是否还可以打卡成功,测试表明,当没有网的时候,是无法获取书的页码,虽然最后可以打卡,但是打卡没有页码,并且打卡消息也是无法发出的。

     

     5.PSP

  • 相关阅读:
    fork子进程
    多输入使用多线程
    多输入select
    多输入之轮询
    开启telnet
    slickedit编译调试linux应用程序
    电子书框架
    通用Makefile
    STDIN_FILENO和stdin
    libiconv交叉编译提示arm-none-linux-gnueabi-gcc
  • 原文地址:https://www.cnblogs.com/ping2yingshi/p/16204216.html
Copyright © 2020-2023  润新知