beat2 发表于 2024-11-5 16:32

需要制作一个JavaScript爬取脚本

本帖最后由 beat2 于 2024-11-17 22:54 编辑

这是之前发布的悬赏帖
需要制作一个JavaScript爬取脚本
https://www.52pojie.cn/thread-1972660-1-1.html
(出处: 吾爱破解论坛)

大家帮忙看看不使用下面这个接口有没有办法获取指定的信息
http://service.bot.qch86.top:8100/activation/code/${page}


获取激活码列表中所有2天、1天、0天前更新的激活码的JavaScript
https://s3.bmp.ovh/imgs/2024/10/15/897b0ba2d9bc8842.png



const days = 2
const today = new Date(new Date().setHours(0, 0, 0, 0))
const oneDay = 86400 * 1000
const daysMap = {
"今": today,
"昨": today - oneDay,
}
let list = []
const activationList = document.querySelectorAll(.activation-list .activation)

async function getList() {
const activationList = setNewList(document.querySelectorAll(.activation-list .activation))
list = [...filterData(activationList,days)]
console.log(list)
if (!list.length){
    return alert(没有数据)
} else {
    const result = list.map(item => {
      return item.content
    }).join(n)
    alert(result)
}
}

const setNewList = (data) => {
return Array.prototype.map.call(data, item => {
    const createTime = daysMap.innerText.split(天)] ? daysMap.innerText.split(天)] : today - oneDay * item.children.innerText.split(天)
    console.log(createTime);
   
    return {
      createTime,
      content: item.children.innerText
    }
})
}

// 过滤掉days之前的数据
const filterData = (data, days) => {
const dates = new Date(new Date().setHours(0, 0, 0, 0))
return data.filter(item => {
    console.log(dates - new Date(item.createTime).getTime() < days * oneDay);
   
    return dates - new Date(item.createTime).getTime() < days * oneDay
})
}
const createObserver =() => {
// 创建观察器
const observer = new MutationObserver(mutations => {
getList()
})
observer.observe(document.querySelector(.activation-list), {
childList: true
})
}
window.onload = createObserver()


但是报错;
不通过接口获取激活码.user.js:18 Uncaught SyntaxError: Unexpected token . (at 不通过接口获取激活码.user.js:18:50)
    at async Wt (injected.js:1:8803)
    at async injected.js:1:14574

beat2 发表于 2024-11-6 23:56

顶ffhfddggfdffdddfffffgffg

beat2 发表于 2024-11-10 12:59


顶ffhfddggfdffdddfffffgffg

beat2 发表于 2024-11-17 22:53

顶ffhfddggfdff

znevue 发表于 2024-11-20 12:44

从接口获取是最方便的,要不就是爬取网站上的信息,得有这个网址啊

beat2 发表于 2024-11-22 01:57

znevue 发表于 2024-11-20 12:44
从接口获取是最方便的,要不就是爬取网站上的信息,得有这个网址啊

这个是网址
http://bot93001.qch86.top/activation?t=1732211802189

superychen 发表于 2024-11-22 11:29

没太看懂你想要啥,写了个油猴脚本,你看满不满足你需求

会在页面右上角显示个提取按钮,可以输入天数自动提取N天内的激活码,然后一键复制到剪贴板

没有图床就不放截图了

// ==UserScript==
// @name         自动提取激活码
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description自动提取激活码
// @AuThor       superychen
// @match      http://bot93001.qch86.top/activation
// @match      http://bot93001.qch86.top/activation?*
// @grant      none
// ==/UserScript==

(function () {
    'use strict';

    // 创建UI元素的通用函数
    function createUIElement(type, options) {
      const element = document.createElement(type);
      Object.assign(element, options.props || {});
      element.style.cssText = options.style || '';
      if (options.text) element.textContent = options.text;
      return element;
    }

    // 创建UI组件
    const ui = {
      button: createUIElement('button', {
            text: '开始提取',
            style: `
                position: fixed;
                right: 20px;
                top: 20px;
                z-index: 9999;
                padding: 10px;
                background: #4CAF50;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
            `
      }),
      input: createUIElement('input', {
            props: { type: 'number', value: '2', min: '1' },
            style: `
                position: fixed;
                right: 120px;
                top: 20px;
                z-index: 9999;
                padding: 8px;
                width: 60px;
                border: 1px solid #ccc;
                border-radius: 4px;
            `
      }),
      label: createUIElement('span', {
            text: '天数:',
            style: `
                position: fixed;
                right: 190px;
                top: 23px;
                z-index: 9999;
                color: #666;
            `
      }),
      resultArea: createUIElement('div', {
            style: `
                position: fixed;
                right: 20px;
                top: 70px;
                width: 300px;
                max-height: 80vh;
                background: white;
                border: 1px solid #ccc;
                border-radius: 4px;
                padding: 10px;
                overflow-y: auto;
                z-index: 9999;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                display: none;
            `
      }),
      copyButton: createUIElement('button', {
            text: '一键复制',
            style: `
                padding: 4px 8px;
                background: #4CAF50;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                display: none;
            `
      }),
      resultCount: createUIElement('div', {
            style: 'font-weight: bold;'
      })
    };

    // 状态管理
    const state = {
      isScrolling: false,
      scrollInterval: null,
      processedItems: new Set(),
      totalProcessed: 0
    };

    // 工具函数
    const utils = {
      parseTimeText(timeText) {
            if (timeText.includes('今天')) return 0;
            if (timeText === '昨天更新' || timeText === '1天前更新') return 1;
            if (timeText === '前天更新' || timeText === '2天前更新' || timeText === '两天前更新') return 2;
            const match = timeText.match(/^(\d+)天前更新$/);
            return match ? parseInt(match) : 999;
      },

      copyToClipboard(text) {
            const textarea = createUIElement('textarea', {
                props: { value: text },
                style: 'position: fixed; left: -9999px;'
            });
            document.body.appendChild(textarea);
            try {
                textarea.select();
                return document.execCommand('copy');
            } finally {
                document.body.removeChild(textarea);
            }
      },

      updateResultCount(message) {
            ui.resultCount.textContent = message;
      },

      stopScrolling() {
            clearInterval(state.scrollInterval);
            state.isScrolling = false;
            ui.button.textContent = '开始提取';
            ui.button.style.background = '#4CAF50';
            utils.updateResultCount(state.totalProcessed > 0
                ? `已完成, 总共找到 ${state.totalProcessed} 条数据`
                : '没有满足条件的数据');
            if (!state.totalProcessed) ui.copyButton.style.display = 'none';
      }
    };

    // 初始化结果区域
    const resultHeader = createUIElement('div', {
      style: `
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
      `
    });
    resultHeader.append(ui.resultCount, ui.copyButton);
    ui.resultArea.appendChild(resultHeader);

    // 事件处理
    ui.copyButton.addEventListener('click', () => {
      const contents = Array.from(state.processedItems)
            .map(key => {
                const = key.split('-');
                return `${time} ${content}`;
            })
            .join('\n');

      if (utils.copyToClipboard(contents)) {
            const originalText = ui.copyButton.textContent;
            ui.copyButton.textContent = '已复制!';
            ui.copyButton.style.background = '#666';
            setTimeout(() => {
                ui.copyButton.textContent = originalText;
                ui.copyButton.style.background = '#4CAF50';
            }, 1000);
      }
    });

    ui.button.addEventListener('click', () => {
      if (!state.isScrolling) {
            // 重置状态
            state.processedItems.clear();
            state.totalProcessed = 0;
            ui.resultArea.innerHTML = '';
            ui.resultArea.appendChild(resultHeader);
            ui.copyButton.style.display = 'none';
            ui.resultArea.style.display = 'block';
            window.scrollTo(0, 0);

            const daysLimit = parseInt(ui.input.value) || 2;
            state.isScrolling = true;
            ui.button.textContent = '停止滚动';
            ui.button.style.background = '#f44336';
            utils.updateResultCount('正在查找...');

            let foundOutOfRange = false;

            state.scrollInterval = setInterval(() => {
                const isLoading = document.querySelector('.van-list')?.getAttribute('aria-busy') === 'true';
                const isFinished = document.querySelector('.van-list__finished-text')?.textContent.includes('没有更多了');

                if (isFinished) {
                  utils.stopScrolling();
                  return;
                }

                document.querySelectorAll('.activation').forEach(item => {
                  const content = item.querySelector('.content').textContent;
                  const time = item.querySelector('.time').textContent;
                  const days = utils.parseTimeText(time);
                  const key = `${time}-${content}`;

                  if (!state.processedItems.has(key)) {
                        if (days < daysLimit) {
                            state.totalProcessed++;
                            utils.updateResultCount(`正在查找, 已找到 ${state.totalProcessed} 条数据`);
                            ui.copyButton.style.display = 'block';

                            const resultItem = createUIElement('div', {
                              style: `
                                    margin-bottom: 10px;
                                    padding: 8px;
                                    background: #f5f5f5;
                                    border-radius: 4px;
                              `,
                              props: {
                                    innerHTML: `
                                        <div style="color: #666; font-size: 12px;">${time}</div>
                                        <div style="margin-top: 4px;">${content}</div>
                                    `
                              }
                            });
                            ui.resultArea.appendChild(resultItem);
                            state.processedItems.add(key);
                        } else {
                            foundOutOfRange = true;
                        }
                  }
                });

                if (foundOutOfRange) {
                  utils.stopScrolling();
                  return;
                }

                if (!isLoading && !foundOutOfRange) {
                  window.scrollBy(0, 100);
                }
            }, 100);
      } else {
            utils.stopScrolling();
      }
    });

    // 添加元素到页面
    document.body.append(ui.label, ui.input, ui.button, ui.resultArea);
})();

superychen 发表于 2024-11-22 11:33

superychen 发表于 2024-11-22 11:29
没太看懂你想要啥,写了个油猴脚本,你看满不满足你需求

会在页面右上角显示个提取按钮,可以输入天数自 ...

贴的代码不知道为啥头里的内容格式乱了,看这里吧 https://netcut.cn/p/df3050bd66abfbf9

znevue 发表于 2024-11-22 18:49

我用插件弄了个网页监听,会将更新的内容推送到微信,如果能满足你的要求可以回我

beat2 发表于 2024-11-23 06:09

znevue 发表于 2024-11-22 18:49
我用插件弄了个网页监听,会将更新的内容推送到微信,如果能满足你的要求可以回我

没看见页面右上角显示提取按钮
页: [1] 2
查看完整版本: 需要制作一个JavaScript爬取脚本