自动化篇 - 躺着收钱!闲鱼自动发货机器人来啦~


​目 标 场 景

闲鱼上,不少卖家选择在平台上卖虚拟商品,大部分虚拟商品的交易方式都是经过网盘连接来完成交易。node

在不少时候,商品被买家拍下并付款后,都须要一段时间的等待,一直到卖家看到消息后才能完成发货,这样显得商品的交易效率很低下。android

那能不能作到「自动发货、自动上新」,全程自动化操做发货呢?答案是确定的。web

本篇文章的目的是为闲鱼定制一个「自动发货机器人」,实现商品自动发货的功能。
bash


编 写 代 码

上篇文章 已经实现了消息自动回复的功能,本篇文章将继续在这个基础之上去实现自动发货机器人的功能。ide

首先,咱们须要根据聊天界面,对订单的状态进行分类。ui


闲鱼中一个商品的订单状态包含:交易前、等待买家付款、等待卖家发货、退款等多种状态。spa

这里,咱们只须要把交易前和等待卖家发货两种状态给筛选出来。code

/*** * 判断订单的状态 */public static int getOrderStatus(AccessibilityNodeInfo node){    List<AccessibilityNodeInfo> status_nodes = node.findAccessibilityNodeInfosByViewId(Ids.id_order_status);    int status = 0;    if (null == status_nodes || 0 == status_nodes.size())    {        status = -1;    } else    {        AccessibilityNodeInfo first_node = status_nodes.get(0);        String status_content = first_node.getText().toString();        //交易前的普通对话        if (TextUtils.equals("交易前聊一聊", status_content))        {             status = 0;        } else if (TextUtils.equals("等待卖家发货", status_content))        {             status = 1;        } else if (TextUtils.equals("等待买家付款", status_content))        {             status = 2;        } else        {             status = 3;        }     }     return status;}复制代码

而后编写 UI 界面,将发货连接地址输入到输入框内,点击保存,保存到本地内存中。orm

//输入发货内容,好比网盘地址String content = delivery_rebot_content_et.getEditableText().toString().trim();if (TextUtils.isEmpty(content)){    SnackbarUtils.Short(delivery_rebot_set_content_btn, "请先输入要发货的内容").show();} else{    SettingConfig.getInstance().setAutoDeliverContent(content);                    delivery_rebot_content_et.getEditableText().clear();                    SnackbarUtils.Long(delivery_rebot_set_content_btn, "设置发货成功!!!").show();}复制代码


当判断当前页面是聊天界面,而且订单状态是「等待卖家发货」时,就从内存中读取数据,将网盘连接地址以消息的形式发送给买家。cdn

//卖家已拍下,自动发货//发货的内容,通常是网盘地址String content = SettingConfig.getInstance().getAutoDeliverContent();//回复内容reply_content(event, content);复制代码


发完消息后,接着查找右上角的「去发货」元素,执行点击操做,模拟去发货。


监听到到达「发货界面」的事件以后,查找右上角的「无需寄件」元素,再进行一次点击操做。

//发货界面 Activitypublic static String class_name_deliver = "com.taobao.idlefish.webview.WebHybridActivity";/*** * 判断是不是发货界面 */public static boolean judgeIsDeliverPage(AccessibilityNodeInfo node){    boolean result = false;    List<AccessibilityNodeInfo> center_node = node.findAccessibilityNodeInfosByViewId(Ids.id_center_title);    List<AccessibilityNodeInfo> right_node = node.findAccessibilityNodeInfosByViewId(Ids.id_right_up);    if (center_node != null && right_node != null && center_node.size() > 0 && right_node.size() > 0 &&                center_node.get(0).getText().equals("我要发货") && right_node.get(0).getText().equals("无需寄件")        )    {            result = true;    }    return result;}/*** * 发货界面处理 * @param event */private void handleDeliverMet(AccessibilityEvent event){    AccessibilityNodeInfo rightNode = findViewByIDAndText(Ids.id_right_up, "无需寄件");    performViewClick(rightNode);}复制代码


经过上面的操做,会弹出一个用于确认发货的对话框。


咱们接着使用 Android Monitor 查看当前页面的元素信息,发现这个页面除了标题栏,内容区都包含在一个「WebView」里面。


因为元素包含在 WebView 里,若是直接利用上面的方式查找对话框中的「文本内容为继续」的按钮元素是获取不到的。

这里须要对配置文件进行修改,增长一个「flags」的属性,保证能获取到当前页面包含 Web 元素的全部元素内容。

@Overrideprotected void onServiceConnected(){    super.onServiceConnected();    AccessibilityServiceInfo serviceInfo = new AccessibilityServiceInfo();    serviceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;    serviceInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;    serviceInfo.packageNames = new String[]{"com.taobao.idlefish"};    serviceInfo.notificationTimeout = 100;    //保证可以获取到Web元素    serviceInfo.flags = serviceInfo.flags | AccessibilityServiceInfo.FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY;    setServiceInfo(serviceInfo);}复制代码


而后先获取到 WebView 元素,再遍历查找筛选其子元素。

/*** * 查找WebView的控件,若是找到,执行点击操做 * @param content */public void findWebViewByTextAndClick(String content){    AccessibilityNodeInfo rootNode = findViewByID(Ids.id_webview_root);    if (rootNode != null)    {        for (int i = 0; i < rootNode.getChildCount(); i++)        {            AccessibilityNodeInfo child = rootNode.getChild(i);            if ("com.uc.webview.export.WebView".contentEquals(child.getClassName()))            {                findEveryViewNode(child, content);                break;            }         }     } else     {            Log.e("xag", "webview rootview is null");     }}复制代码


当查找到一个元素文本内容为肯定,而且元素「可点击」,就执行点击操做,即完成了当前商品发货的操做。

private void findEveryViewNode(AccessibilityNodeInfo node, String content){    if (null != node && node.getChildCount() > 0)    {        for (int i = 0; i < node.getChildCount(); i++)        {            AccessibilityNodeInfo child = node.getChild(i);            // 有时 child 为空            if (child == null)            {                continue;            }            String className = child.getClassName().toString();            CharSequence text_raw = child.getText();            if ("android.view.View".equals(className) && !TextUtils.isEmpty(text_raw))            {                boolean isClickable = child.isClickable();                Log.e("xxx", "内容是:" + text_raw.toString());                //isClickable:可点击的按钮,按钮内容是继续                if (isClickable && TextUtils.equals(content, text_raw.toString()))                {                   child.performAction(AccessibilityNodeInfo.ACTION_CLICK);                   break;                }             }             // 递归调用             findEveryViewNode(child, content);          }       }}复制代码


结 果 结 论

完成发货以后,执行全局返回的操做,直到页面从新回到闲鱼主界面为止。

固然,也能够在发货完成以后,点击这个商品的从新编辑按钮,修改后再次发布商品,这样就能够实现一件商品「 自动发货、自动上新 」的循环操做。

我已经将所有源码上传到公众号后台上,关注公众号「AirPython」后回复「 发货机器人 」便可得到下载连接。

另外,我也整理一份正确运营闲鱼的思惟导图,有须要的能够关注公众号后回复「 闲鱼脑图 」获取。

若是你以为文章还不错,请你们点赞分享下。你的确定是我最大的鼓励和支持。


推荐阅读:

自动化篇 - 为闲鱼制做一个客服机器人(上)

自动化篇 - 黑客们使用的自动化方案,不少人还不知道

相关文章
相关标签/搜索