autoxjs 安卓爬虫自动化

autoxjs 安卓爬虫自动化

我这里只是测试请勿用于违法的

我这里是小红书


文章目录


前言

欢迎来到AutoXJS的世界,这是一个充满创新、挑战和技术探索的领域。在这个引领未来的时刻,我们怀揣着对技术的热情,探索着自动化领域的无尽可能性。

AutoXJS旨在推动JavaScript自动化的前沿,探索先进的工具、框架和最佳实践,使开发者能够更高效、更智能地构建出色的应用程序。这不仅仅是一个技术社区,更是一个激发创意、分享知识的聚集地。

我们致力于连接那些对JavaScript和自动化充满热情的人,无论是初学者还是经验丰富的开发者。在AutoXJS,你将发现深入的技术讨论、实用的开发指南以及引领未来的前瞻性思考。


提示:以下是本篇文章正文内容,下面案例可供参考

一、自动刷直播间并且抓取商品已经粉丝数量等?

抓到的数据

下面是执行的视频的效果:
视频链接

代码:

js 复制代码
var xiaohong_backpack_name = "com.xingin.xhs";
app.launch(xiaohong_backpack_name);
sleep(100)
clickByUiSelector('text', "首页");
var width = device.width; // 获取设备的宽度
var height = device.height; // 获取设备的高度
var duration = 500; // 滑动动作持续的时间
// 从屏幕的1/4高度位置滑动到3/4高度位置,模拟下拉动作
swipe(width / 2, height / 4, width / 2, height * 3 / 4, duration);
sleep(2000)
clickByUiSelector('desc', "直播");
sleep(200)
clickNearElement('desc', "直播", -100, 100);
sleep(1000)


var resultArray = []; // 存储最终结果
var usernameSet = new Set(); // 存储用户名,用于去重
var currentDownSwipeCount = 0; // 当前下滑次数
function scrollAndFetch() {
    // 循环7次下滑
    for (var down = 0; down < 7; down++) {
        if (currentPackage() !== xiaohong_backpack_name) {
            console.log("已离开小红书应用,暂停滑动操作。");
            return; // 退出函数
        }
        currentDownSwipeCount = down; 
        var titleElements = id("com.xingin.xhs:id/dl6").find();
        var viewerElements = id("com.xingin.xhs:id/dho").find();
        var usernameElements = id("com.xingin.xhs:id/djk").find();
        var clickAttempts = {};
        for (var i = 0; i < titleElements.length; i++) {
            var viewerCount = parseViewerCount(viewerElements[i].text());
            var titleText = titleElements[i].text();
            if (viewerCount > 2000 && !usernameSet.has(usernameElements[i].text())) {// 观看人数大于4000且用户名未存储过 
                clickAttempts[titleText] = (clickAttempts[titleText] || 0) + 1; // 增加点击次数    
                console.log("大于2000");           
               
                if (clickAttempts[titleText] <= 3) { // 限制最多点击3次
                    sleep(1000)
                    clickNearElement('text', titleText, 0,-480);
                    sleep(1000)
                    if (checkIfLivePage()) {
                        live_streaming_entry(usernameElements[i].text(),titleElements[i].text(),viewerElements[i].text(),usernameElements[i].text())
                        usernameSet.add(usernameElements[i].text());
                    }else {
                        return;
                    }
                }else {
                    console.log("点击尝试超过3次,跳过标题:" + titleText);
                    continue;
                }
               
                
            }
        }
        if (currentDownSwipeCount === down && currentPackage() === xiaohong_backpack_name && !id("com.xingin.xhs:id/s2").findOne(3000)) {
            swipe(width / 2, height * 3 / 4, width / 2, height / 4, 500);
            sleep(1000); // 等待内容加载
        }
       
    }

    // 循环7次上滑回到顶部
    for (var up = 0; up < 7; up++) {
        if (currentPackage() !== xiaohong_backpack_name && id("com.xingin.xhs:id/s2").findOne(5000)) {
            console.log("已离开小红书应用,暂停滑动操作。");
            return; // 退出函数
        }
        swipe(width / 2, height / 4, width / 2, height * 3 / 4, 500);
        sleep(2000); // 等待页面滑动和加载
    }

    // 模拟下拉刷新
    if (currentPackage() === xiaohong_backpack_name && !id("com.xingin.xhs:id/s2").findOne(2000)) {
        swipe(width / 2, height / 4, width / 2, height * 3 / 4, 500);
        sleep(1000);
    } else {
        console.log("已离开小红书应用,未执行刷新操作。");
    }
}



function saveDataToJsonFile(data) {
    // 设置文件路径和名字
    var path = "/storage/emulated/0/脚本/get_danmu/test/data.json"; 
    // 将对象转换为字符串
    var dataString = JSON.stringify(data, null, 4);
    // 写入文件
    files.write(path, dataString);

    console.log("数据已保存到文件: " + path);
}

while (true) { // 持续循环执行
    if (currentPackage() === xiaohong_backpack_name) {
        console.log("当前包名称",currentPackage())
        scrollAndFetch(); // 调用滑动和数据捕获函数
        saveDataToJsonFile(resultArray); // 保存数据到文件
        console.log(JSON.stringify(resultArray, null, 4)); // 打印当前结果
        currentDownSwipeCount = 0; 
    } else {
        console.log("不在小红书应用内,脚本暂停运行。");
        for (let i = 0; i < 30; i++) { // 等待总时长为5分钟(每次暂停10秒,检查30次)
            sleep(10000); // 暂停10秒
            if (currentPackage() === xiaohong_backpack_name) {
                console.log("重新进入小红书应用,继续执行脚本。");
                break; // 如果重新进入小红书应用,则跳出等待循环
            }
        }
    }
}





function parseViewerCount(viewerString) {
    if (viewerString.includes('W') || viewerString.includes('w')) {
        // 去除'W',转换为数值后乘以10000
        return parseFloat(viewerString.replace(/W|w/g, '')) * 10000;
    } else {
        // 直接转换为数值
        return parseInt(viewerString.replace(/\D/g, ''));
    }
}



// 点击直播进入
function live_streaming_entry(usernameElements,title, viewers, username){
   var _l = id("com.xingin.xhs:id/s2").findOne();
   _l && _l.click() || console.log("没有找到指定ID的元素");
    sleep(1000)
    clickByUiSelector('text', usernameElements,2000);
    sleep(1000)
    if (checkTextExists("举报", 3000)) {  // 假设点击成功后会出现"举报"文本
        console.log("未成功点击,重试...");
        var _ll = id("com.xingin.xhs:id/esk").findOne(2000);
        _ll && _ll.click() || console.log("没有找到指定ID的元素");
        sleep(1000);
    }
    clickByUiSelector('text', "取消");
    sleep(1000)
    var fansElement = id("com.xingin.xhs:id/bkb").findOne(3000);
    var likesElement = id("com.xingin.xhs:id/dfp").findOne(3000);
    
    var fans = fansElement ? fansElement.text() : "没有抓到";
    var likes = likesElement ? likesElement.text() : "没有抓到";
    sleep(800)

    if(fans != "没有抓到" || likes != "没有抓到") {
         // 计算起始点和结束点的坐标
    var startX = width * 3 / 4;  // 从屏幕宽度的3/4处开始滑动
    var endX = width / 10;       // 到屏幕宽度的1/4处结束滑动
    // var y = height * 2 / 3;
    var y = height * 3 / 4; 
    // 执行滑动动作
    swipe(startX, y, endX, y, duration);

    sleep(800)
    clickByUiSelector('text', "销量");
    sleep(1000)

        var productNameElement = id("com.xingin.xhs:id/gh5").findOne(2000)
        var priceElement  = id("com.xingin.xhs:id/hp1").findOne(2000)
        var salesVolumeElement = id("com.xingin.xhs:id/a1j").findOne(2000)

        var productName = productNameElement ? productNameElement.text() : "没有抓到";
        var price = priceElement ? priceElement.text() : "没有抓到";
        var salesVolume = salesVolumeElement ? salesVolumeElement.text() : "没有抓到";
       
        resultArray.push({
            标题: title,
            观看人数: viewers,
            用户名: username,
            粉丝: fans,
            收藏: likes,
            商品名称: productName,
            价格: price,
            销量: salesVolume
        });
        
        console.log("标题", title);
        console.log("观看人数", viewers);
        console.log("用户名", username);
        console.log("商品名称", productName);
        console.log("价格", price);
        console.log("销量", salesVolume);
        console.log("粉丝", fans);
        console.log("收藏", likes);
        
    }
    back();
    sleep(1000);
    back();
    sleep(1000);
   
}



function checkTextExists(textToCheck, timeout) {
    return text(textToCheck).findOne(timeout) != null;
}

function clickByUiSelector(selectorType, valueToClick, timeout){
    // 设置默认超时时间为1000毫秒
    timeout = timeout || 1000; 
    var uiObject;

    // 根据selectorType选择查找方式
    if(selectorType === 'text'){
        console.log("点击文本:" + valueToClick);
        uiObject = text(valueToClick).findOne(timeout);
    } else if(selectorType === 'desc'){
        uiObject = desc(valueToClick).findOne(timeout);
    } else {
        console.log("未知的选择器类型:" + selectorType);
        return false;
    }

    // 进行点击操作
    if(uiObject != null){
        uiObject.click();
        return true; // 点击成功
    } else {
        console.log("没有找到:" + valueToClick);
        return false; // 没有点击,因为没有找到对象
    }
}


function checkIfLivePage() {
    // 根据页面特定元素来判断是否为直播页面
    var livePageIndicator = id("com.xingin.xhs:id/s2").findOne(2000);
    return livePageIndicator !== null;
}


function clickNearElement(selectorType, valueToFind, offsetX, offsetY){
    var uiObject;

    // 根据selectorType选择查找方式
    if(selectorType === 'text'){
        uiObject = text(valueToFind).findOne();
    } else if(selectorType === 'desc'){
        uiObject = desc(valueToFind).findOne();
    } else {
        console.log("未知的选择器类型:" + selectorType);
        return false;
    }

    // 检查是否找到UI对象
    if (uiObject != null) {
        // 计算新的点击位置
        var x = uiObject.bounds().centerX() + offsetX;
        var y = uiObject.bounds().centerY() + offsetY;

        // 执行点击操作
        click(x, y);
        return true;
    } else {
        console.log("没有找到指定的文本或描述:" + valueToFind);
        return false;
    }
}

总结

我这里写了一个测试,更多业务请自行

相关推荐
DP DPharness6 小时前
浏览器自动化插件时,三个可核对的判断维度
运维·自动化
迁移科技6 小时前
无惧焊接强光与飞溅:Epic Eye Pixel Welding特定工况相机解析
人工智能·科技·自动化·视觉检测
传奇开心果编程7 小时前
【Compose Multiplatform 跨端开发学与练】第8课 资源管理与主题
android·windows·学习·ios·kotlin·web·composer
传奇开心果编程8 小时前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
传奇开心果编程9 小时前
【Compose Multiplatform 跨端开发学与练】第4课 导航与路由
android·windows·学习·ui·ios·kotlin·composer
传奇开心果编程9 小时前
【Compose Multiplatform 跨端开发学与练】第6课 状态管理与架构
android·学习·ui·ios·架构·kotlin·composer
事圆则缓9 小时前
Android AOSP 定制常见概念:源码目录、系统镜像与刷机流程
android
传奇开心果编程9 小时前
【Compose Multiplatform 跨端开发学与练】第2课 Compose 基础语法
android·windows·学习·ui·ios·kotlin·composer
supabc12310 小时前
Celium:连接 Windows、Mac、Linux 与 Android,让远程访问和设备管理更简单
android·linux·windows·macos·远程访问·网络管理·celium
Dovis(誓平步青云)10 小时前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物