油猴脚本注入js获取DY作品数据

news2024/9/29 19:14:57

油猴脚本的执行时机: 元素还未生成
https://bbs.tampermonkey.net.cn/thread-3843-1-1.html

而在控制台执行时, 通常元素已经生成

逻辑就是在网页每次发送请求时, 拦截它请求的响应数据作操作; 所以当用户作品很多时, 也需要一直滚动到全部作品请求加载完成, 触发下载
(当然这都可以改 什么时候触发下载)

// ==UserScript==
// @name         抖音个人主页作品抓取注入
// @namespace    http://tampermonkey.net/
// @version      2024-01-18
// @description  try to take over the world!
// @author       You
// @match        https://www.douyin.com/user/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=douyin.com
// @grant        none
// ==/UserScript==

(function() {
'use strict';

// 通过 hook XMLHttpRequest 的 send 方法,捕获返回的数据
let aweme_post_list = [];
let page = 0;

// 1. 保存原始的 send 方法
const nativeXMLHttpRequestSend = XMLHttpRequest.prototype.send;

// 2. 重写 send 方法
XMLHttpRequest.prototype.send = function (body) {
    // https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readystatechange_event

    // XMLHttpRequest.readyState 属性返回一个 XMLHttpRequest 代理当前所处的状态, 4表示下载操作已完成。
    // https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/readyState

    // console.log('body', body);
    this.addEventListener('readystatechange', function () {
        console.debug({
            'readyState': this.readyState,
            'status': this.status,
            'responseURL': this.responseURL
        });
        // 响应正常完成
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {

            if (this.responseURL.includes('/aweme/v1/web/aweme/post/')) {
                // 3. 解析返回数据
                let json_data = JSON.parse(this.responseText);
                console.log(`${++page}页, 本页${json_data.aweme_list.length}条作品`);

                const data = json_data.aweme_list.map(item => {
                    const { aweme_id, desc: title, create_time, video: { play_addr: { url_list: play_addr_list } } } = item;
                    const create_date = new Date(create_time * 1000);
                    const addr = 'https://www.douyin.com/video/' + aweme_id;
                    return { aweme_id, title, create_date, addr, play_addr_list };
                })
                aweme_post_list = aweme_post_list.concat(data);

                // 判断是否完成
                if (json_data.has_more === 0) {
                    console.log(`全部完成, 共${aweme_post_list.length}条作品, 开始下载...`);
                    downloadAwemePostJson(aweme_post_list, 'aweme_post_list.json');

                    // 下載視頻
                    aweme_post_list.forEach((item, index) => {
                        const title = legalizationFilename(item.title);
                        const filename = `${index + 1}-${title}.mp4`;
                        downloadAwemePostVideo(item.play_addr_list[0], filename);
                    });
                }
            }

        }

    });
    // 4. 调用原始的 send 方法
    return nativeXMLHttpRequestSend.call(this, body);
}




/**
 * 将JS对象保存为JSON文件
 * @param {object} data 需要下载的JS对象
 */
function downloadAwemePostJson(data, filename) {
    let blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    let a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = filename;
    a.click();
}

/**
 * 下載抖音作品視頻
 * @param {*} url
 * @param {*} filename
 */
function downloadAwemePostVideo(url, filename) {
    url = url.replace('http://', 'https://');
    fetch(url)
        .then(res => res.blob())
        .then(blob => {
            console.debug(url, filename);
            const a = document.createElement("a");
            const objectUrl = URL.createObjectURL(blob);
            a.download = filename;
            a.href = objectUrl;
            a.click();
            URL.revokeObjectURL(objectUrl);
            a.remove();
        }).catch(err => {
            console.error(err);
        });
}
/**
 * 合法化文件名
 * @param {*} filename
 * @returns
 */
function legalizationFilename(filename) {
    return filename.replace(/[\\/:*?"<>|]/g, '');
}
})();

其实DY本生也重写了XHR的send方法, 也可能是框架重写的
在这里插入图片描述

视频演示:

2.89 09/20 RKW:/ w@S.yG 油猴脚本js注入批量下载DY视频 https://v.douyin.com/iLfWLdeo/ 复制此链接,打开Dou音搜索,直接观看视频!

参考:
【小红书数据采集教学(2)通过重写XMLHttpRequest的send方法来获取POST响应体数】https://www.bilibili.com/video/BV1VC4y1e7RR?vd_source=603d76094f4b03d34ae4f468d5e77227

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1396030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库经典面试题

习题一 1.1 创建表 ①创建Student表 mysql> create table Student ( -> Sno int primary key, -> Sname varchar(255), -> Ssex varchar(10), -> Sdept varchar(50) -> ); Query OK, 0 rows affected (0.01 sec) ②创建Course表 mysql…

树莓派4B +Ubuntu20.04+ROS1的使用(2)

首先确定一下主机与从机的ip地址&#xff08;非常重要&#xff09; 在这次实验中&#xff0c;主机是一台Ubuntu20.04.03系统的台式机&#xff0c;我们间通过这台准备来远程遥控树莓派上的ros1系统&#xff0c;它的ip地址是192.168.230.181 从机是一台搭载Ubuntu20.04桌面版ro…

项目管理十大知识领域之项目人力资源管理

一、项目人力资源管理的概述 作为项目管理的重要组成部分&#xff0c;项目人力资源管理旨在有效管理和利用项目团队的人力资源&#xff0c;以实现项目目标。它涵盖了对人员的招聘、培训、激励和绩效管理等方面&#xff0c;旨在确保项目团队的高效运转和成员的专业发展。项目人…

录课视频太大怎么办?3种方法一键瘦身~

录制视频是现代人常用的一种记录生活的方式&#xff0c;但是视频文件大小往往会很大&#xff0c;不利于存储和分享。为了解决这个问题&#xff0c;我们需要使用视频压缩软件来压缩视频文件大小&#xff0c;以便更方便地存储和分享。 方法一&#xff1a;嗨格式压缩大师 嗨格式压…

el-tree获取当前选中节点及其所有父节点的id(包含半选中父节点的id)

如下图,我们现在全勾中的有表格管理及其下的子级,而半勾中的有工作台和任务管理及其子级 现在点击保存按钮后,需要将勾中的节点id及该节点对应的父节点,祖先节点的id(包含半选中父节点的id)也都一并传给后端,那这个例子里就应该共传入9个id,我们可以直接将getCheckedK…

【b站咸虾米】chapter4_vue组件_新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握

课程地址&#xff1a;【新课uniapp零基础入门到项目打包&#xff08;微信小程序/H5/vue/安卓apk&#xff09;全掌握】 https://www.bilibili.com/video/BV1mT411K7nW/?p12&share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 四、vue组件 uni-app官网 …

【面试】测试/测开(ING3)

190. 栈和堆在内存管理上的区别 栈 1&#xff09; 栈是由系统自动分配和回收的内存。 2&#xff09;栈的存储地址是由高地址向低地址扩展的。 3&#xff09;栈是一个先进后出的结构。 4&#xff09;栈的空间大小是一个在编译时确定常数&#xff0c;即栈的大小是有限制的&#x…

Windows连接Ubuntu桌面

平时Windows连接Ubuntu服务器都是使用Xshell、FinalShell等工具&#xff0c;但这些连接之后只能通过终端进行操作&#xff0c;无法用桌面方式与服务器交互。 本文介绍如何通过工具&#xff0c;实现Window连接远程Ubuntu服务器&#xff0c;并使用桌面方式交互。 系统版本&#x…

C/C++ BM5 合并K个已排序的链表

文章目录 前言题目1 解决方案一1.1 思路阐述1.2 源码 2 解决方案二2.1 思路阐述2.2 源码 总结 前言 在接触了BM4的两个链表合并的情况&#xff0c;对于k个已排序列表&#xff0c;其实可以用合并的方法来看待问题。 这里第一种方法就是借用BM4的操作&#xff0c;只不过是多个合…

Redis内部数据结构ziplist详解

什么是ziplist Redis官方对于ziplist的定义是&#xff08;出自ziplist.c的文件头部注释&#xff09;&#xff1a; The ziplist is a specially encoded dually linked list that is designed to be very memory efficient. It stores both strings and integer values, where …

three.js 缓动算法.easing(渐入相机动画)

效果&#xff1a;淡入&#xff0c;靠近物体 代码&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div c…

go实现判断20000数据范围内哪些是素数(只能被1和它本身整除的数),采用多协程和管道实现

实现一个并发程序&#xff0c;用于寻找 20000 以内的所有素数。使用了 Goroutines 和 Channels 来分发和处理任务&#xff0c;并通过 WaitGroup&#xff08;实现为 exitChan&#xff09;来同步 Goroutines 的退出。 一.GO代码 package mainimport ("fmt""time…

docker安装confluence全套流程

docker安装confluence全套流程 1.安装mysql2.创建mysql容器3.拉取confluence7容器4.拷贝mysql驱动到confluence中:1195ef11d768为容器id(需要修改为你自己的)5.创建confluence容器6.激活confluence到数据连接可能需报数据库编码和环境隔离错误 1.安装mysql docker pull mysql/…

保姆版Vps安装灯塔(ARL)

因为灯塔的默认端口为5003&#xff0c;所以我们在安装之前就在防火墙里把我们的5003端口打开 打开端口步骤如下&#xff1a; 1.我们打开控制面板&#xff0c;在控制面板里点击 系统和安全 。如下图&#xff1a; 2.接着点击 Windows Defender防火墙,如下图&#xff1a; 3.再…

好用的流程图工具

分享工作中常用的装逼工具 目前市面上的流程图或者思维导图工具挺多的&#xff0c;但是有的会限制使用数量或者收费&#xff0c;典型的有processon、Xmind&#xff0c;推荐今天Mermaid(官网)。 快速上手 中文教程&#xff1a;Mermaid 初学者用户指南 | Mermaid 中文网。我们选择…

Spring | Spring中的Bean--下

Spring中的Bean: 4.Bean的生命周期5.Bean的配装配式 ( 添加Bean到IOC容器的方式 依赖注入的方式 )5.1 基于XML的配置5.2 基于Annotation (注解) 的装配 (更常用&#xff09;5.3 自动装配 4.Bean的生命周期 Spring容器可以管理 singleton作用域的Bean的生命周期&#xff0c;在此…

51单片机_电压采集器电压表

实物演示效果&#xff1a; https://www.bilibili.com/video/BV1My4y1F7xY/?vd_source6ff7cd03af95cd504b60511ef9373a1d 一、基本功能 利用51单片机作为主控芯片&#xff0c;3段式电压采集。模拟量经A/D&#xff08;ADC0809&#xff09;模数转换芯片&#xff0c;把模拟量转换…

【计算机网络】(1)OSI七层模型、协议、交换技术、路由器技术

文章目录 计算机网络功能与分类计算机网络的定义计算机网络的功能计算机网络的指标计算机网络的性能指标计算机网络的非性能指标 计算机网络的分布范围以及拓扑结构划分图计算机网络分类总线型拓扑星型拓扑环形图拓扑树型拓扑分布式拓扑 通信技术信道物理信道逻辑信道 发信机OS…

微信小程序(六)tabBar的使用

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1. 标签栏文字的内容以及默认与选中颜色 2. 标签栏图标的默认样式与选中样式 3. 标签选项路径页面 4.标签栏背景颜色 &#x1f43c;&#xff08;文末补充&#xff09;设置标签栏后为什么navigator标签无法跳转页…

ros2仿真学习04 -turtlebot3实现cartographer算法建图演示

安装看这里 https://blog.csdn.net/hai411741962/article/details/135619608?spm1001.2014.3001.5502 虚拟机配置&#xff1a; 内存16g cpu 4 核 磁盘40G,20G 不够 启动仿真 ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py启动成功如下 启动建图 重新开一个…