Greasy Fork

获取弹幕_DOM版

在线获取抖音巨量百应弹幕

目前为 2024-02-01 提交的版本。查看 最新版本

// ==UserScript==
// @name         获取弹幕_DOM版
// @namespace    http://tampermonkey.net/
// @version      2.0.0
// @description  在线获取抖音巨量百应弹幕
// @author       37
// @match        https://buyin.jinritemai.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// @license MIT
// @require     http://libs.baidu.com/jquery/2.0.0/jquery.min.js
// @require     https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
// ==/UserScript==

(function () {
    'use strict';
    let ws;
    let observer;
    let waitMsgList = [];
    let stopWs = false;
    let goodsList = []
    let wxUrl = ''
    let promotionsList = []
    function connectWebSocket() {
        ws = new WebSocket(wxUrl);
        ws.addEventListener('open', () => {
            console.log('连接成功')
            const submitButton = document.querySelector('#submitButton');
            submitButton.textContent = '断开弹幕采集';

            if (waitMsgList.length) {
                waitMsgList.forEach((item) => {
                    ws.send(item);
                    console.log('成功发送缓存---', item);
                });
                waitMsgList = [];
            }

        });
        ws.addEventListener('message', event => {
            console.log('从服务器接收到消息:', JSON.parse(event.data));
            JSON.parse(event.data).type == 3 && findGoods(JSON.parse(event.data).answerText[0])
        });
        ws.addEventListener('close', (event) => {
            const submitButton = document.querySelector('#submitButton');
            submitButton.textContent = '连接弹幕采集';
            if (stopWs) {
                stopWs = false
            } else {
                setTimeout(() => {
                    console.log('WebSocket 已关闭--正在重新连接');
                    connectWebSocket(wxUrl);
                }, 3000);
            }
        });
    }

    function startObserver() {
        observer = new MutationObserver(mutationsList => {
            mutationsList.forEach(mutation => {
                mutation.addedNodes.forEach(addedNode => {
                    if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('index-module__commentItem___2fLb5')) {
                        const userElement = addedNode.querySelector('.index-module__nickname___L6O_K');
                        const contentElement = addedNode.querySelector('.index-module__description___2W_id');
                        if (contentElement) {
                            const dataToSend = {
                                answerText: contentElement.textContent,
                                type: 1
                            };
                            if (ws && ws.readyState === 1) {
                                ws.send(JSON.stringify(dataToSend));

                                console.log('成功发送弹幕---', userElement.textContent, contentElement.textContent);
                            } else {

                                console.log('储存弹幕一条---', userElement.textContent, contentElement.textContent);
                                waitMsgList.push(JSON.stringify(dataToSend));
                            }
                        }
                    }
                    if (addedNode.nodeType === Node.ELEMENT_NODE && addedNode.classList.contains('index-module__newCommentShadow___3rffn')) {
                         console.log('监测到需要加载新弹幕')
                         document.querySelectorAll(".index-module__newCommentShadow___3rffn")[0].click()
                    }
                });
            });
        });
        observer.observe(document.documentElement, { childList: true, subtree: true });
    }
    function getGoodsList() {
        const match = wxUrl.match(/websocket\/([^\/]+)/);
        if (match ? match[1] : null) {
            $.ajax({
                type: "GET",
                url: "https://buyin.jinritemai.com/api/anchor/livepc/promotions",
                success: function (data) {
                    promotionsList = data.data.promotions
                    goodsList = data.data.promotions.map((data, index) => {
                        return {
                            goodName: data.title,
                            goodNo: index + 1,
                            price: data.min_price / 100,
                            liveId: match[1],
                        }
                    })
                    const dataToSend = {
                        answerText: goodsList,
                        type: 4
                    };
                    ws.send(JSON.stringify(dataToSend));
                    alert('更新商品成功')
                }
            });
        } else { console.log('获取liveID失败') }

    }
    function findGoods(item){
        $.ajax({
            type: "POST",
            url: "https://buyin.jinritemai.com/api/anchor/livepc/setcurrent",
            data: { promotion_id: promotionsList[item.goodNo - 1].promotion_id },
            success: function (data) {
                document.querySelectorAll(".index__actionItem___2Z8YV")[1].click()
            }
        });
    }
    function stopObserver() {
        if (observer) {
            observer.disconnect();
            observer = null;
        }
    }
    function disconnectWebSocket() {
        if (ws) {
            ws.close();
            stopObserver()
            stopWs = true
            console.log('WebSocket 已手动断开连接');
        }
    }

    function createFloatingInput() {

        const inputContainer = document.createElement('div');
        inputContainer.style.position = 'fixed';
        inputContainer.style.top = '60px';
        inputContainer.style.left = '20px';
        inputContainer.style.zIndex = '999999';

        const inputElement = document.createElement('input');
        inputElement.setAttribute('type', 'text');
        inputElement.setAttribute('placeholder', '输入 WebSocket 地址');
        inputElement.classList.add('input-box');
        inputElement.style.padding = '8px';
        inputElement.style.border = '1px solid #ccc';
        inputElement.style.borderRadius = '4px';
        inputElement.style.outline = 'none';

        const submitButton = document.createElement('button');
        submitButton.id = 'submitButton'
        submitButton.textContent = '连接弹幕采集';
        submitButton.style.marginLeft = '8px';
        submitButton.style.padding = '8px';
        submitButton.style.border = '1px solid #ccc';
        submitButton.style.borderRadius = '4px';
        submitButton.style.backgroundColor = '#f0f0f0';
        submitButton.style.cursor = 'pointer';

        const goodsButton = document.createElement('button');
        goodsButton.id = 'submitButton'
        goodsButton.textContent = '更新抖音商品';
        goodsButton.style.marginLeft = '8px';
        goodsButton.style.padding = '8px';
        goodsButton.style.border = '1px solid #ccc';
        goodsButton.style.borderRadius = '4px';
        goodsButton.style.backgroundColor = '#f0f0f0';
        goodsButton.style.cursor = 'pointer';

        submitButton.addEventListener('click', () => {
            const inputVal = inputElement.value.trim();
            if (inputVal) {
                if (ws && ws.readyState == 1) {
                    disconnectWebSocket();
                } else {
                    startObserver()
                    wxUrl = inputVal
                    connectWebSocket(inputVal);
                }
            }
        });
        goodsButton.addEventListener('click', () => {
            getGoodsList()
        });
        inputContainer.appendChild(inputElement);
        inputContainer.appendChild(submitButton);
        inputContainer.appendChild(goodsButton);
        document.body.appendChild(inputContainer);
    }
    createFloatingInput();

})();