星之子 发表于 2024-10-3 06:02:46

【油猴脚本】帖子内容提取 活动员会用到的妙妙工具

本帖最后由 星之子 于 2024-10-3 06:05 编辑

动机
最近想收集一下周年庆【星辰降临】活动的绝版勋章发放数据,然后在勋章公会发个帖子——但工作量确实很大,回帖格式也没有完全规范,真要一页一页整理还不如直接嘎了我。另外也是受到了 @墨燝 老师写的 活动内容爬取工具 (表格版) 的启发,所以就调教GPT写了这个脚本(感觉自己好像那种赛博奴隶主,天天压榨GPT这个赛博奴隶这是可以说的吗)。

功能
仅在形如 https://www.gamemale.com/thread-*(帖子ID)-*(页码)-1.html 的网站中生效:

[*]按下快捷键Ctrl+Y后,自动提取当前页面上所有回帖的作者UID及其回帖内容(忽略格式,仅提取纯文本)
[*]这些内容将会被合并为一行,换行将被替换为用户指定的特定符号(默认全角分号,可在代码中修改)
[*]将内容每行一个,合并为“extracted_text-帖子ID-页码.txt”下载到本地
[*]然后跳转到帖子的下一页,方便再次按下快捷键Ctrl+Y,进行下一次提取
重复上述过程,直至帖子的最后一页。

优点:

[*]简单易行门槛低,无需提取cookie和运行python
[*]抗干扰性强,忽略格式提取所有回帖的文本内容
[*]适用范围更广,无需特定格式也可提取
[*]访问量相对合理(相当于手动浏览一遍帖子,速度不会很快但也够用,3秒按一次快捷键相当于1分钟20页)
[*]可以选择是否提取“本帖最后由 someone 于 yyyy-m-d hh:mm 编辑”信息(默认忽略,可在代码中修改)

缺点:

[*]导出结果一页一个.txt,需要借助其它工具合并
[*]需要善用Excel的数据-分列功能自行补足成表格



代码
@Name
// ==UserScript==
// @name         看帖:活动员神器 帖子内容提取
// @namespace    https://www.gamemale.com/space-uid-733330.html
// @version      2.1
// @description忽略格式提取所有回帖的文本内容,将换行用指定分隔符代替,并前缀UID,每回帖一行,并按照当前页码命名
// @author       Étoiles
// @match      https://www.gamemale.com/thread-*-*-1.html
// @icon         https://www.google.com/s2/favicons?sz=64&domain=gamemale.com
// @grant      none
// ==/UserScript==

(function () {
    'use strict';
    //在这里调整是否忽略“本帖最后由 someone 于 yyyy-m-d hh:mm 编辑” 开启:1 关闭:0
    const IGNORE_PSTATUS = 1;

    //在这里修改触发按钮,默认Ctrl+Y
    document.addEventListener('keydown', function (event) {
      if (event.ctrlKey && event.key === 'y') {

            let elements = document.querySelectorAll('td.t_f, div.authi');
            let contentArray = [];
            let currentAuthorId = '';

            elements.forEach(function (element) {
                if (element.classList.contains('authi')) {
                  let authorElement = element.querySelector('a');
                  if (authorElement) {
                        let authorIdMatch = authorElement.href.match(/space-uid-(\d+)\.html/);
                        if (authorIdMatch) {
                            //这里的★只是一个标识符,方便确认这是脚本自动添加的UID而非回复内容里的
                            currentAuthorId = `★${authorIdMatch}`;
                        }
                  }
                } else if (element.classList.contains('t_f')) {
                  let clone = element.cloneNode(true);

                  //忽略 <i class="pstatus"> 本帖最后由 someone 于 yyyy-m-d hh:mm 编辑 </i> 和紧随其后的<br>
                  if (IGNORE_PSTATUS) {
                        let pstatusElements = clone.querySelectorAll('i.pstatus');
                        pstatusElements.forEach(function (pstatusElement) {
                            let nextSibling = pstatusElement.nextSibling;
                            for (let i = 0; i < 2; i++) {
                              if (nextSibling && nextSibling.nodeName === 'BR') {
                                    let toRemove = nextSibling;
                                    nextSibling = nextSibling.nextSibling;
                                    toRemove.remove();
                              }
                            }
                            pstatusElement.remove();
                        });
                  }


                  //脚本会把一个用户的帖子合并为一行,将换行符替换为某个特定分隔符
                  //在这里可以调整分隔符,默认是半角分号(感觉这个分号不常用)可在 ↓ 这里修改
                  let textContent = clone.innerHTML.replace(/<br\s*\/?>/gi, ';').replace(/<[^>]+>/g, '').replace(/^\s*;/g, '').replace(/\s+/g, ' ').trim();
                  if (currentAuthorId) {
                        textContent = currentAuthorId + ';' + textContent;
                        currentAuthorId = ''; // Reset after using
                  }
                  contentArray.push(textContent);
                }
            });

            //基于当前帖子ID和页码给文件命名
            let currentUrl = window.location.href;
            let match = currentUrl.match(/thread-(\d+)-(\d+)-(\d+)\.html/);
            let filename = 'extracted_text';
            if (match) {
                let threadId = match;
                let currentPage = match;
                filename = `extracted_text-${threadId}-${currentPage}`;
            }

            let blob = new Blob(, { type: 'text/plain' });
            let link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = filename + '.txt';
            link.click();

            //自动跳转到下一页
            if (match) {
                let threadId = match;
                let currentPage = parseInt(match);
                let nextPage = currentPage + 1;
                let newUrl = currentUrl.replace(/thread-(\d+)-(\d+)-(\d+)\.html/, `thread-${threadId}-${nextPage}-$3.html`);
                window.location.href = newUrl;
            }
      }
    });
})();

附录
Excel 分列教程(以【疯狂之旅】疯狂山庄-报名登记 第一页为例)


星象占卜

zzy159 发表于 2024-10-3 06:53:44

哇哦,有了这个脚本对活动员统计不是方便多惹;P

dwsleyi 发表于 2024-10-3 07:24:36

上次虫群活动有这个脚本,活动员就轻松多了
不过理论上按键精灵也能实现{:6_185:}

alexwang 发表于 2024-10-3 07:40:11

好像这个功能适合村里的版主和活动员使用便于统计活动惹

前方无怪 发表于 2024-10-3 08:10:19

好耶!这下子活动数据统计的话极为方便啦,可以省出不少时间、精力呢{:5_143:}~

凯诺斯 发表于 2024-10-3 08:35:21

直接提取内容对活动员来说太方便了惹,很实用的脚本{:6_169:}

tuxonstar 发表于 2024-10-3 08:37:00

非常实用的小工具啊,方便活动员!

娱乐法师火布偶 发表于 2024-10-3 08:58:53

真是非常方便的工具了,很多活动真是可以用到呢

咸鱼鱼 发表于 2024-10-3 09:05:17

可以先疯狂点击下一页,把所有页面加载完成
然后再一次性提取,这样更加省事一点

PURO_ 发表于 2024-10-3 09:22:09

这样活动进度都可以顺利很多快很多,挺方便的

you9632587 发表于 2024-10-3 09:24:43

能忽略格式和空格还是方便多了,之前格雷用脚本之前还要一个一个去手动改格式

Blackless 发表于 2024-10-3 09:30:06

非常好用的小工具啊,以后活动就更加方便了

黑夜下的灯光 发表于 2024-10-3 09:34:56

感觉相当实用的工具呢,做起事情来更加方便了呢

黑达克 发表于 2024-10-3 09:57:27

示例图:#星之子强取无怪#(bushi)
不用特定格式也能提取到是方便不少。

user_login 发表于 2024-10-3 09:57:30

实现上舍近求远了,我就不指手画脚了

枫糖 发表于 2024-10-3 10:00:29

真的很会写脚本,膜拜了

Morphyus 发表于 2024-10-3 10:16:22

活动员之友系列, 感谢楼主分享

咕里奇 发表于 2024-10-3 10:52:45

对我这类闲鱼没用但是对泥潭的活动员们很有用的脚本,方便活动员也能更好地搞坛内活动了{:6_200:}

不是卖萌的基佬 发表于 2024-10-3 11:03:04

功能挺强大的样子 对活动员帮助很大

提尔特 发表于 2024-10-3 11:03:49

;PGPT这种工具不就是认人使用的吗
页: [1] 2
查看完整版本: 【油猴脚本】帖子内容提取 活动员会用到的妙妙工具