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;
    }
}

总结

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

相关推荐
qq_426003963 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
森叶3 天前
用远程调试端口自动化 Chrome 应用商店发布:做法、三个真坑,以及你必须知道的风险
自动化