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

 

posted @ 2022-04-28 19:35  萍2樱释  阅读(578)  评论(0编辑  收藏  举报