2025年4月15日 星期二 乙巳(蛇)年 正月十六 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

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

时间:10-12来源:作者:点击数:113
城东书院 www.cdsy.xyz

1、目 标 场 景

闲鱼上,很多卖家选择在平台上卖虚拟商品,大部分虚拟商品的交易方式都是通过网盘链接来完成交易。

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

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

图片

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

2、编 写 代 码

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

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

图片

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

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

  • /***
  •  * 判断订单的状态
  •  */
  • 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 界面,将发货链接地址输入到输入框内,点击保存,保存到本地内存中。

  • //输入发货内容,比如网盘地址
  • 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();
  • }

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

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

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

图片

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

  • //发货界面 Activity
  • public 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 元素的所有元素内容。

  • @Override
  • protected 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);
  •           }
  •        }
  • }

3、结 果 结 论

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

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

已经将全部源码上传:https://github.com/xingag/app_spider/tree/master/xianyu_auto2。

另外,也整理一份正确运营闲鱼的思维导图:链接:https://pan.baidu.com/s/1zcAV7VMur91Ld2B1qRLGPQ  密码:8rr6。

城东书院 www.cdsy.xyz
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐