当前位置: 首页 > article >正文

android AccessibilityService合法合规采集大众点评app商店商品详情(2024-09-02)

免责任声明:

        任何可操作性的内容与本人无关,文章内容仅供参考学习,如有侵权损害贵公司利益,请联系作者,会立刻马上进行删除。

一、原理介绍


1、打开大众点评app商店

    public void open_shop(Context context,String shop_id)
    {
        String url="dianping://gcshopshell?shopuuid="+shop_id;
        scroll_count=0;
        Uri uri = Uri.parse(url); //
        Intent intent =new Intent(Intent.ACTION_VIEW,uri);;
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

2、采集如下字段:

    public class Commodity{
        public int id;
        public String title;        //商品标题
        public String price;      //售价
        public String market_price;  //市场价
        public String sales;            //年销量
        public String shop_id;        //商店id
        public String shop_index;
        public int count;
    }

3、 保存数据为Csv文件


            Csv csv1=Csv.getInstance(context);
            boolean bres=csv1.save_commodities(commodities);
            if(bres==false){
                fb.set_show("保存数据失败!请检查有没有数据存储权限!");
                return;
            }

4、滚动屏幕

private void performScroll(AccessibilityNodeInfo rootNode){
        if(mCurrentUI.startsWith("com.dianping.shopshell")){
            AccessibilityNodeInfo scrollNode=AccessibilityHelper.findNodeInfosById(rootNode,"com.dianping.v1:id/pagecontainer_recyclerview",0);
            if(scrollNode!=null) {
                if (scroll_count < 10) {
                    AccessibilityHelper.performScrollForward(scrollNode);
                    AccessibilityNodeInfo firstNode=AccessibilityHelper.findNodeInfoByTextAllMatched(rootNode,"抢购");
                    if(firstNode==null)scroll_count=10;
                }
                else {
                    AccessibilityHelper.performScrollBackward(scrollNode);
                    AccessibilityNodeInfo firstNode=AccessibilityHelper.findNodeInfoByTextAllMatched(rootNode,"封面");
                    if(firstNode!=null)scroll_count=0;
                }
                scroll_count += 1;
                if (scroll_count > 20) {
                    scroll_count = 0;
                }
            }
            //AccessibilityNodeInfo no_moreNode=AccessibilityHelper.findNodeInfosByText(rootNode,"收起",0);
            

        }

5、采集数据

private Commodity get_commodity(AccessibilityNodeInfo buyNode){
        try{
            AccessibilityNodeInfo parent=buyNode.getParent();
            if(parent==null)return null;
            parent=parent.getParent();
            if(parent==null)return null;
            int price_count=0;
            Commodity commodity=new Commodity();
            for (int i = 0; i < parent.getChildCount(); i++) {
                AccessibilityNodeInfo child=parent.getChild(i);
                if(child!=null&&child.getText()!=null){
                    String text=child.getText().toString();
                    text=text.replaceAll(",","[comma]");
                    commodity.shop_id=shop_id;
                    commodity.shop_index=String.valueOf(csv.shop_index);
                    commodity.count=commodity_count;
                    if(i==0){
                        //if(isInCommodities(text))return null;
                        commodity.title=text;
                    }
                    if(text.startsWith("年售"))commodity.sales=text;
                    if(text.startsWith("全国爆卖"))commodity.sales=text;
                    if(text.startsWith("¥")){
                        if(price_count==0)
                            commodity.price=text;
                        else
                        if(price_count==1)
                            commodity.market_price=text;
                        price_count+=1;
                    }

                }
            }
            if(isInCommodities(commodity))return null;
            return commodity;
        }catch (Exception e){
            MyLog.e(e);
            return null;
        }
    }
    private boolean isInCommodities(String title){
        for (Commodity commodity:commodities){
            if(title.equals(commodity.title))return true;
        }
        return false;
    }

6、获取商品数量并点击更多,展开商品信息

  private void performMoreClick(AccessibilityNodeInfo rootNode){
        if(commodity_count>0)return;
        AccessibilityNodeInfo moreNode=AccessibilityHelper.findNodeInfosByText(rootNode,"个团购",0);
        if(moreNode!=null) {
            String text=moreNode.getText().toString();
            if(text.startsWith("更多")){
                AccessibilityNodeInfo parent=moreNode.getParent();
                if(parent==null)return;
                if(parent.getClassName().toString().equals("android.widget.LinearLayout")){
                    MyLog.i("找到:"+text);
                    int more=Funcs.getDigital(text);
                    if(more>0)commodity_count=more+5;
                    show_count();
                    AccessibilityHelper.performClick(moreNode);
                }
            }
            return;
        }
        moreNode=AccessibilityHelper.findNodeInfosByText(rootNode,"个商品",0);
        if(moreNode!=null) {
            String text=moreNode.getText().toString();
            if(text.indexOf("更多")>0){
                String say="非美容院商店...跳过";
                FloatWindowButton fb=FloatWindowButton.getInstance(context);
                fb.set_show(say);
                Csv csv1=Csv.getInstance(context);
                boolean bres=csv1.save_no_shop_id(shop_id,String.valueOf(csv1.shop_index));
                if(bres==false){
                    fb.set_show("保存数据失败!请检查有没有数据存储权限!");
                    return;
                }
                open_next_shop_prepare(Config.interval,false);
            }
            return;
        }
    }

二、完整源代码


package accessibility.app;
import accessibility.AccessibilityFindByText;
import accessibility.AccessibilityHelper;
import accessibility.BaseAccessibilityJob;
import accessibility.AccService;
import floatwindow.FloatWindowButton;
import utils.Config;
import utils.Csv;
import utils.Funcs;
import utils.MyLog;

import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Toast;

import com.dp.jp.MainActivity;

import java.util.ArrayList;
import java.util.List;

public class ShopInfoJob  extends BaseAccessibilityJob{
    public static final int STAT_NONE=0;
    public static final int STAT_WORKING=1;
    public static final int STAT_WAITING=2;
    public static int state=0;
    private static ShopInfoJob current;
    private utils.Csv csv;
    private int scroll_count=0;

    public String CurrentUI=null;
    public String shop_id=null;
    private boolean is_alarm=false;
    //--------------------------------------------------------------------------
    public List<Commodity> commodities=new ArrayList<Commodity>() ;
    public boolean isBusy=false;
    private int commodity_count=0;
    private ShopInfoJob() {
        //super(new String[]{Config.PKG_IM_TOKEN,Config.PKG_HUOBI,Config.PKG_BTD});
        super(new String[]{"com.dianping.v1"});
        //super(null);技术支持:metabycf or byc6352
        csv= Csv.getInstance(context);
    }
    public static synchronized ShopInfoJob getInstance() {
        if(current == null) {
            current = new ShopInfoJob();
        }
        return current;
    }
    @Override
    public void onCreateJob(AccService service) {
        super.onCreateJob(service);
        EventStart();


    }
    @Override
    public void onStopJob() {
        super.onStopJob();

    }
    /*
     * (刷新处理流程)
     * @see accessbility.AccessbilityJob#onWorking()
     */
    @Override
    public void onWorking(){
        FloatWindowButton fb=FloatWindowButton.getInstance(context);
        String say="正在执行任务...";
        if(commodity_count>0&&commodities.size()>=commodity_count){

            say="采集完成...";
            fb.set_show(say);
            Csv csv1=Csv.getInstance(context);
            boolean bres=csv1.save_commodities(commodities);
            if(bres==false){
                fb.set_show("保存数据失败!请检查有没有数据存储权限!");
                return;
            }
            AccessibilityHelper.performBack(service);
            Funcs.sleep(2);

            open_next_shop_prepare(Config.interval,false);
            return;
        }
        AccessibilityNodeInfo rootNode = service.getRootInActiveWindow();
        if (rootNode == null) return;

        fb.set_show(say);
        //com.dianping.shopshell.GCShopInfoActivity
        if(rootNode.getPackageName().toString().equals("com.dianping.v1")){
            if(mCurrentUI.startsWith("com.dianping.shopshell.")) {
                performMoreClick(rootNode);
                performScroll(rootNode);

            }
       }


    }
    @Override
    public void onReceiveJob(AccessibilityEvent event) {
        super.onReceiveJob(event);
        if(!mIsEventWorking)return;
        if(!mIsTargetPackageName)return;
        CurrentUI=mCurrentUI;
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
        {
            MyLog.i("mCurrentUI="+mCurrentUI);
            if(mCurrentUI.startsWith("com.dianping.shopshell.")){
                if(state==STAT_WORKING) {

                }
                if(is_alarm)
                    Funcs.alarm(context,false);
            }
            if(mCurrentUI.startsWith("android.app.Dialog")){
                if(Config.auto_close_verify){
                    AccessibilityNodeInfo rootNode=event.getSource();
                    if(rootNode==null)return;
                    //close_verify_btn(rootNode);
                }else {
                    Funcs.alarm(context,true);
                    is_alarm=true;
                }

            }
            if(mCurrentUI.startsWith("com.meituan.android.yoda.activity.YodaConfirmActivity")){
                if(Config.auto_close_verify){
                    AccessibilityNodeInfo rootNode=event.getSource();
                    if(rootNode==null)return;
                    //close_verify_back(rootNode);
                }else {
                    Funcs.alarm(context,true);
                    is_alarm=true;
                }

            }


        }
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED)
        {
            if(commodity_count>0&&commodity_count==commodities.size())return;
            if(mCurrentUI.startsWith("com.dianping.shopshell.")){
                if(state==STAT_WORKING) {
                    AccessibilityNodeInfo rootNode=event.getSource();
                    if(rootNode==null)return;
                    pluck_from_shop(rootNode);
                    TimeStart();
                    performMoreClick(rootNode);
                }
            }

        }

    }
    //---------------------------------------------------------------------
    //"dianping://gcshopshell?shopuuid=H44paDfKZflcSGHd"
    public void open_shop(Context context,String shop_id)
    {
        String url="dianping://gcshopshell?shopuuid="+shop_id;
        scroll_count=0;
        Uri uri = Uri.parse(url); //
        Intent intent =new Intent(Intent.ACTION_VIEW,uri);;
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
    /*
    1.浮动窗口:下一个
    2.working.over
    3.主窗口:继续
    4.accservice open
     */
    public void open_next_shop_prepare(int delay,boolean cur){
        if(runnableStart!=null)return;

        state=STAT_WAITING;
        //et_cur_id.setText(String.valueOf(csv1.commodities_index));
        runnableStart = new Runnable() {
            @Override
            public void run() {
                try {
                    Csv csv1=Csv.getInstance(context);
                    if(cur)
                        shop_id=csv1.get_shop_id();
                    else
                        shop_id=csv1.get_next_shop_id();
                    FloatWindowButton fb=FloatWindowButton.getInstance(context);
                    fb.ShowFloatWindow();
                    if(csv1.shop_index>Config.end_id||csv1.shop_index>csv1.get_shop_total_count()||shop_id.equals("")){
                        String say="已完成任务";
                        fb.set_show(say);
                        runnableStart=null;
                        return;
                    }
                    state=STAT_WORKING;
                    String say="开始执行任务...";
                    fb.set_show(say);
                    fb.set_commodity_count_show(String.valueOf(csv1.shop_index));
                    open_shop(context,shop_id);
                    commodities.clear();
                    commodity_count=0;
                    runnableStart=null;

                }catch (Exception e){
                    MyLog.e(e.getMessage().toString());
                }

            }
        };
        handler.postDelayed(runnableStart, delay);
    }

    //private boolean pluck_start=false;
    //private int pluck_count=0;
    //private Commodity commodity=null;

    private void pluck_from_shop(AccessibilityNodeInfo rootNode){
        try{
            if(mCurrentUI.startsWith("com.dianping.shopshell.")){
                if(isBusy)return;
                isBusy=true;
                try{
                    //com.dianping.v1:id/pagecontainer_recyclerview
                    //AccessibilityNodeInfo pagecontainerNode=AccessibilityHelper.findNodeInfosById(rootNode,"com.dianping.v1:id/pagecontainer_recyclerview",0);
                    //if(pagecontainerNode!=null){
                        List<AccessibilityNodeInfo>  buyNodes=AccessibilityHelper.findNodeInfosByTextAllMatched(rootNode,"抢购");
                        if(buyNodes==null||buyNodes.size()==0)return;
                        for (AccessibilityNodeInfo buyNode:buyNodes){
                            Commodity commodity=get_commodity(buyNode) ;
                            if(commodity!=null)commodities.add(commodity);
                        }
                        show_count();
                    //}
                }catch (Exception e){
                    MyLog.e(e.getMessage().toString());
                    return ;
                }finally {
                    isBusy=false;
                }
            }
        }catch (Exception e){
            MyLog.e(e.getMessage().toString());

        }
    }


    private void performScroll(AccessibilityNodeInfo rootNode){
        if(mCurrentUI.startsWith("com.dianping.shopshell")){
            AccessibilityNodeInfo scrollNode=AccessibilityHelper.findNodeInfosById(rootNode,"com.dianping.v1:id/pagecontainer_recyclerview",0);
            if(scrollNode!=null) {
                if (scroll_count < 10) {
                    AccessibilityHelper.performScrollForward(scrollNode);
                    AccessibilityNodeInfo firstNode=AccessibilityHelper.findNodeInfoByTextAllMatched(rootNode,"抢购");
                    if(firstNode==null)scroll_count=10;
                }
                else {
                    AccessibilityHelper.performScrollBackward(scrollNode);
                    AccessibilityNodeInfo firstNode=AccessibilityHelper.findNodeInfoByTextAllMatched(rootNode,"封面");
                    if(firstNode!=null)scroll_count=0;
                }
                scroll_count += 1;
                if (scroll_count > 20) {
                    scroll_count = 0;
                }
            }
            //AccessibilityNodeInfo no_moreNode=AccessibilityHelper.findNodeInfosByText(rootNode,"收起",0);
            //if(no_moreNode!=null&&no_moreNode.getText()!=null&&no_moreNode.getText().toString().startsWith("收起")) scroll_count=10;

        }

    }





    private Commodity get_commodity(AccessibilityNodeInfo buyNode){
        try{
            AccessibilityNodeInfo parent=buyNode.getParent();
            if(parent==null)return null;
            parent=parent.getParent();
            if(parent==null)return null;
            int price_count=0;
            Commodity commodity=new Commodity();
            for (int i = 0; i < parent.getChildCount(); i++) {
                AccessibilityNodeInfo child=parent.getChild(i);
                if(child!=null&&child.getText()!=null){
                    String text=child.getText().toString();
                    text=text.replaceAll(",","[comma]");
                    commodity.shop_id=shop_id;
                    commodity.shop_index=String.valueOf(csv.shop_index);
                    commodity.count=commodity_count;
                    if(i==0){
                        //if(isInCommodities(text))return null;
                        commodity.title=text;
                    }
                    if(text.startsWith("年售"))commodity.sales=text;
                    if(text.startsWith("全国爆卖"))commodity.sales=text;
                    if(text.startsWith("¥")){
                        if(price_count==0)
                            commodity.price=text;
                        else
                        if(price_count==1)
                            commodity.market_price=text;
                        price_count+=1;
                    }

                }
            }
            if(isInCommodities(commodity))return null;
            return commodity;
        }catch (Exception e){
            MyLog.e(e);
            return null;
        }
    }
    private boolean isInCommodities(String title){
        for (Commodity commodity:commodities){
            if(title.equals(commodity.title))return true;
        }
        return false;
    }
    private boolean isInCommodities(Commodity commodity_new){
        try {
            for (Commodity commodity:commodities){
                if(Funcs.isEqua(commodity_new.title,commodity.title)&&Funcs.isEqua(commodity_new.price,commodity.price)&&Funcs.isEqua(commodity_new.sales,commodity.sales))return true;
            }
            return false;
        }catch (Exception e){
            MyLog.e(e);
            return false;
        }
    }
    private void performMoreClick(AccessibilityNodeInfo rootNode){
        if(commodity_count>0)return;
        AccessibilityNodeInfo moreNode=AccessibilityHelper.findNodeInfosByText(rootNode,"个团购",0);
        if(moreNode!=null) {
            String text=moreNode.getText().toString();
            if(text.startsWith("更多")){
                AccessibilityNodeInfo parent=moreNode.getParent();
                if(parent==null)return;
                if(parent.getClassName().toString().equals("android.widget.LinearLayout")){
                    MyLog.i("找到:"+text);
                    int more=Funcs.getDigital(text);
                    if(more>0)commodity_count=more+5;
                    show_count();
                    AccessibilityHelper.performClick(moreNode);
                }
            }
            return;
        }
        moreNode=AccessibilityHelper.findNodeInfosByText(rootNode,"个商品",0);
        if(moreNode!=null) {
            String text=moreNode.getText().toString();
            if(text.indexOf("更多")>0){
                String say="非美容院商店...跳过";
                FloatWindowButton fb=FloatWindowButton.getInstance(context);
                fb.set_show(say);
                Csv csv1=Csv.getInstance(context);
                boolean bres=csv1.save_no_shop_id(shop_id,String.valueOf(csv1.shop_index));
                if(bres==false){
                    fb.set_show("保存数据失败!请检查有没有数据存储权限!");
                    return;
                }
                open_next_shop_prepare(Config.interval,false);
            }
            return;
        }
    }
    private void show_count(){
        String say="";
        if(commodity_count==0)
            say="当前商店编号:"+String.valueOf(csv.shop_index)+"已找到商品数:"+String.valueOf(commodities.size());
        else
            say="当前商店编号:"+String.valueOf(csv.shop_index)+"共有商品数:"+String.valueOf(commodity_count)+"已找到商品数:"+String.valueOf(commodities.size());
        FloatWindowButton.getInstance(context).set_commodity_count_show(say);
    }












    private Runnable runnableStart=null;
    private Handler handler = new Handler();









    public class Commodity{
        public int id;
        public String title;
        public String price;
        public String market_price;
        public String sales;
        public String shop_id;
        public String shop_index;
        public int count;
    }

}

技术支持:

UVHvvJozOTg0ODg3MuW+ruS/oe+8mmJ5YzYzNTLmiJZtZXRhYnljZueUteaKpe+8mmJ5YzAx (base64解码)


http://www.kler.cn/news/294941.html

相关文章:

  • 【Qt笔记】QListWidget控件详解
  • 经济管理专业数据库介绍
  • 算法学习:模拟
  • Unity Adressables 使用说明(三)构建内容(Build Content)
  • 85、 探针
  • Java基础 1. Java开发环境搭建
  • 数据处理与数据填充在Pandas中的应用
  • 基于 RocketMQ 的云原生 MQTT 消息引擎设计
  • 智能体叙事实验:MixlabNodes新增Her页面
  • Android --- observer和observerForever的区别
  • Ansible自动化运维入门:从基础到实践的全面指南
  • 福建聚鼎科技:开一家装饰画店铺需要投资多少钱
  • Java|Java 中 JSONPath 的使用
  • history增加时间显示
  • PostgreSQL的repmgr工具介绍
  • centos基本命令
  • 店匠科技携手Stripe共谋电商支付新篇章
  • 漫谈设计模式 [14]:迭代器模式
  • 人工智能与机器学习原理精解【16】
  • Mac M1 安装Hadoop教程(安装包安装)
  • keepalived和lvs高可用集群
  • 一次关于生产环境服务无故宕机的排查过程
  • 顶刊精析|METI:整合细胞形态与空间转录组学的肿瘤微环境分析框架·24-09-06
  • MySQL面试题大全和详解,含SQL例子
  • EF框架删除数据
  • Hive是什么?
  • 模型压缩之剪枝
  • Openharmony 图片自适应全屏显示
  • C++系统教程002-数据类型(01)
  • pytorch torch.gather函数介绍