VSThouse 搜索结果合并全部页并时间倒序

自动抓取 1-10 页结果,合并后按发布时间倒序

当前为 2025-09-02 提交的版本,查看 最新版本

// ==UserScript==
// @name         VSThouse 搜索结果合并全部页并时间倒序
// @namespace    https://example.com
// @version      2.0
// @description  自动抓取 1-10 页结果,合并后按发布时间倒序
// @author       Ginkoro with Kimi K2
// @match        https://vsthouse.ru/search/*
// @grant        none
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    /* ---------- 工具函数 ---------- */
    const parseDate = str => new Date(str.replace(' ', 'T') + 'Z').getTime();

    const getTimeFromBlock = block => {
        const d = block.querySelector('.eDetails');
        if (!d) return 0;
        const m = d.textContent.match(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/);
        return m ? parseDate(m[0]) : 0;
    };

    /* 把一段 HTML 字符串转成 Document */
    const htmlToDoc = html => {
        const parser = new DOMParser();
        return parser.parseFromString(html, 'text/html');
    };

    /* ---------- 抓取全部页(自动识别真实总页数) ---------- */
    async function fetchAllPages() {
        const urlObj = new URL(location.href);
        const baseQ = urlObj.searchParams.get('q');
        const container = document.querySelector('.content-padding');
        if (!container) return;

        /* 1. 先清空当前结果 & <br>,保留分页条 */
        const pager = container.querySelector('div[align="center"]');
        container.querySelectorAll('table.eBlock, br').forEach(n => n.remove());

        /* 2. 抓第 1 页并解析出“最后一页”按钮的页码 */
        const firstResp = await fetch(location.href, { credentials: 'include' });
        const firstDoc = htmlToDoc(await firstResp.text());
        const lastLink = firstDoc.querySelector('.navigation a:last-of-type, .paging a:last-of-type');
        let totalPages = 1;
        if (lastLink) {
            const m = lastLink.getAttribute('href').match(/[?&]p=(\d+)/);
            if (m) totalPages = Math.min(10, parseInt(m[1], 10)); // 上限仍 10
        }

        /* 3. 并发抓取 1..totalPages */
        const pages = Array.from({ length: totalPages }, (_, i) => i + 1);
        const tasks = pages.map(p => {
            const u = new URL(location.href);
            u.searchParams.set('p', p);
            return fetch(u.href, { credentials: 'include' })
                .then(r => r.text())
                .then(html => htmlToDoc(html));
        });
        const docs = await Promise.all(tasks);

        /* 4. 提取所有结果、排序、插入(与之前相同) */
        const allBlocks = docs.flatMap(doc => Array.from(doc.querySelectorAll('table.eBlock')));
        allBlocks.sort((a, b) => getTimeFromBlock(b) - getTimeFromBlock(a));
        allBlocks.forEach((block, idx) => {
            container.appendChild(block);
            if (idx < allBlocks.length - 1) container.appendChild(document.createElement('br'));
        });
        if (pager) container.appendChild(pager);
    }

    /* ---------- 启动 ---------- */
    fetchAllPages().catch(console.error);
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址