限时秒杀

function startClickingEndButtons() {
    // 初始时,点击所有符合条件的按钮
    clickNextEndButton();
  }
  
  function clickNextEndButton() {
    // 获取所有<td>标签中的<a>标签,查找包含"取消活动"字样的<a>标签
    const allATags = document.querySelectorAll('td a');
    const endTags = [];
  
    // 遍历所有<a>标签,找到包含"取消活动"文本的那个
    allATags.forEach(aTag => {
      if (aTag.textContent.includes('取消活动')) {
        endTags.push(aTag); // 将所有包含"结束"的<a>标签加入endTags数组
      }
    });
  
    if (endTags.length > 0) {
      const nextTag = endTags[0]; // 获取第一个符合条件的标签
      console.log('Clicking button with "取消活动" text');
      nextTag.click(); // 点击第一个符合条件的<a>标签
      
      // 延迟1秒后点击弹出窗口中的"放弃活动"按钮
      setTimeout(() => {
        clickPopupButton();
        // 延迟2秒再继续点击
        setTimeout(() => {
          console.log("Waiting for page update...");
          // 页面更新后,继续点击下一个符合条件的a标签
          clickNextEndButton();
        }, 2000); // 页面刷新后等待2秒
      }, 300); // 等待1秒,确保弹出窗口显示
    } else {
      console.log('No more "放弃活动" buttons found');
    }
  }
  
  // 点击弹出的"确认结束"按钮
function clickPopupButton() {
  // 获取所有具有data-testid="beast-core-button"的button标签
  const buttons = document.querySelectorAll('button[data-testid="beast-core-button"]');
  
  // 遍历所有按钮,查找包含"放弃活动"文本的按钮
  buttons.forEach(button => {
    const span = button.querySelector('span');
    if (span && span.textContent.includes('放弃活动')) {
      console.log('Clicked the confirm end button');
      button.click(); // 点击符合条件的按钮
    }
  });
}  
  // 启动点击操作
  startClickingEndButtons();

已驳回

function startClickingEndButtons() {
    // 初始时,点击所有符合条件的按钮
    clickNextEndButton();
  }
  
  function clickNextEndButton() {
    // 获取所有<td>标签中的<a>标签,查找包含"删除草稿"字样的<a>标签
    const allATags = document.querySelectorAll('td a');
    const endTags = [];
  
    // 遍历所有<a>标签,找到包含"删除草稿"文本的那个
    allATags.forEach(aTag => {
      if (aTag.textContent.includes('删除草稿')) {
        endTags.push(aTag); // 将所有包含"结束"的<a>标签加入endTags数组
      }
    });
  
    if (endTags.length > 0) {
      const nextTag = endTags[0]; // 获取第一个符合条件的标签
      console.log('Clicking button with "删除草稿" text');
      nextTag.click(); // 点击第一个符合条件的<a>标签
      
      // 延迟1秒后点击弹出窗口中的"确认删除"按钮
      setTimeout(() => {
        clickPopupButton();
        // 延迟2秒再继续点击
        setTimeout(() => {
          console.log("Waiting for page update...");
          // 页面更新后,继续点击下一个符合条件的a标签
          clickNextEndButton();
        }, 3000); // 页面刷新后等待2秒
      }, 300); // 等待1秒,确保弹出窗口显示
    } else {
      console.log('No more "确认删除" buttons found');
    }
  }
  
  // 点击弹出的"确认结束"按钮
function clickPopupButton() {
  // 获取所有具有data-testid="beast-core-button"的button标签
  const buttons = document.querySelectorAll('button[data-testid="beast-core-modal-ok-button"]');
  
  // 遍历所有按钮,查找包含"确认删除"文本的按钮
  buttons.forEach(button => {
    const span = button.querySelector('span');
    if (span && span.textContent.includes('确认')) {
      console.log('Clicked the confirm end button');
      button.click(); // 点击符合条件的按钮
    }
  });
}  
  // 启动点击操作
  startClickingEndButtons();

首单&限量

function startClickingEndButtons() {
    // 初始时,点击所有符合条件的按钮
    clickNextEndButton();
  }
  
  function clickNextEndButton() {
    // 获取所有<td>标签中的<a>标签,查找包含"结束"字样的<a>标签
    const allATags = document.querySelectorAll('td a');
    const endTags = [];
  
    // 遍历所有<a>标签,找到包含"结束"文本的那个
    allATags.forEach(aTag => {
      if (aTag.textContent.includes('结束')) {
        endTags.push(aTag); // 将所有包含"结束"的<a>标签加入endTags数组
      }
    });
  
    if (endTags.length > 0) {
      const nextTag = endTags[0]; // 获取第一个符合条件的标签
      console.log('Clicking button with "结束" text');
      nextTag.click(); // 点击第一个符合条件的<a>标签
      
      // 延迟500毫秒后点击弹出窗口中的"确认结束"按钮
      setTimeout(() => {
        clickPopupButton();
        // 延迟2秒再继续点击
        setTimeout(() => {
          console.log("Waiting for page update...");
          // 页面更新后,继续点击下一个符合条件的a标签
          clickNextEndButton();
        }, 2000); // 页面刷新后等待2秒
      }, 500); // 等待500毫秒,确保弹出窗口显示
    } else {
      console.log('No more "结束" buttons found');
    }
  }
  
  // 点击弹出的"确认结束"按钮
  function clickPopupButton() {
    // 获取所有具有data-testid="beast-core-button"的button标签
    const buttons = document.querySelectorAll('button[data-testid="beast-core-button"]');
    
    // 遍历所有按钮,查找包含"确认结束"文本的按钮
    buttons.forEach(button => {
      const span = button.querySelector('span');
      if (span && span.textContent.includes('确认')) {
        console.log('Clicked the confirm end button');
        button.click(); // 点击符合条件的按钮
        // 继续点击 "直接结束" 按钮
        setTimeout(() => {
          clickDirectEndButton();
        }, 500); // 等待500毫秒,确保 "直接结束" 按钮已加载
      }
    });
  }
  
  // 点击弹出的"直接结束"按钮
  function clickDirectEndButton() {
    // 获取具有 "直接结束" 文本的<a>标签
    const directEndButton = document.querySelector('a[data-tracking-viewid="straight_end_shared"]');
    
    if (directEndButton) {
      console.log('Clicked the direct end button');
      directEndButton.click(); // 点击 "直接结束" 按钮
    } else {
      console.log('Direct end button not found');
    }
  }
  
  // 启动点击操作
  startClickingEndButtons();

提取当页ID

// 创建一个函数来提取ID编号并导出为TXT文件
(function () {
    // 查找所有包含ID编号的元素
    const orderElements = document.querySelectorAll('td');

    // 用于存储提取的ID编号
    let orderData = '';

    orderElements.forEach((element) => {
        if (element.innerText.includes('ID')) {
            // 使用正则提取ID编号
            const match = element.innerText.match(/ID:([\d]+)/);
            if (match && match[1]) {
                orderData += match[1].trim() + '\n';
            }
        }
    });

    if (orderData) {
        // 创建一个Blob对象
        const blob = new Blob([orderData], { type: 'text/plain' });

        // 创建一个下载链接
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = 'order_numbers.txt';

        // 触发下载
        document.body.appendChild(link);
        link.click();

        // 移除下载链接
        document.body.removeChild(link);

        console.log('ID编号已成功导出为TXT文件');
    } else {
        console.warn('未找到ID编号');
    }
})();

新版活动提取

// 修正版商品ID提取脚本
const ids = new Set();
let page = 1;

const extractIds = () => {
  console.log(`正在提取第 ${page} 页`);
  // 同时匹配两种可能的元素
  document.querySelectorAll('span[style*="rgba(0, 0, 0, 0.4)"], td')
    .forEach(el => {
      const match = el.textContent.match(/\d{10,}/);
      if (match) ids.add(match[0]);
    });
};

const nextPage = () => {
  const nextBtn = document.querySelector('[data-testid="beast-core-pagination-next"]:not(.PGT_disabled_5-141-0)');
  if (nextBtn) {
    nextBtn.click();
    page++;
    setTimeout(main, 2000); // 保持2秒间隔
  } else {
    exportData();
  }
};

const exportData = () => {
  const content = [...ids].join('\n');
  const blob = new Blob([content], {type: 'text/plain'});
  const link = document.createElement('a');
  link.href = URL.createObjectURL(blob);
  link.download = `提取的商品ID_${new Date().toLocaleString().replace(/[\/:]/g,'-')}.txt`;
  link.click();
  console.log(`✅ 完成!共提取 ${ids.size} 个唯一ID`);
};

const main = () => {
  try {
    extractIds();
    nextPage();
  } catch (e) {
    console.warn('⚠️ 发生错误:', e);
    nextPage(); // 继续尝试下一页
  }
};

// 1秒后开始执行(确保DOM加载)
setTimeout(main, 1000);

商品数据

(async function() {
    console.log("启动采集脚本...");

    // === 配置区 ===
    const NEXT_PAGE_SELECTOR = 'li[data-testid="beast-core-pagination-next"]';
    const WAIT_TIME = 2000; 
    // =============

    const sleep = (ms) => new Promise(r => setTimeout(r, ms));

    // 1. 文件名生成
    function getFileNameMeta() {
        let shopName = "拼多多店铺";
        let dateInfo = "未知时间";
        try {
            const nameEl = document.querySelector('.user-name-text');
            if (nameEl) shopName = nameEl.innerText.trim();

            const dateEl = document.querySelector('[class*="goods-detail_subTitle"]');
            if (dateEl) {
                let text = dateEl.innerText.trim().replace(/统计时间[::]/g, "").trim();
                const timeMatch = text.match(/^\d{4}-\d{2}-\d{2}\s+(\d{2}):(\d{2}):(\d{2})$/);
                if (timeMatch) {
                    dateInfo = `${timeMatch[1]}点${timeMatch[2]}分${timeMatch[3]}秒`;
                } else {
                    dateInfo = text;
                }
            }
        } catch (e) {}
        return `${shopName}_${dateInfo}数据`.replace(/[\\/:*?"<>|]/g, "_").replace(/\s+/g, "_");
    }

    // 2. 提取当前标签
    function getActiveTimeLabel() {
        let label = "今日";
        try {
            const filterContainer = document.querySelector('div[class*="goods-detail_filterWrapper"]');
            if (filterContainer) {
                const activeLabel = filterContainer.querySelector('label[data-testid="beast-core-radio"][data-checked="true"]');
                if (activeLabel) label = activeLabel.innerText.replace(/\n/g, '').trim();
            }
        } catch (e) {}
        return label;
    }

    // 3. 提取单页数据 (核心修改)
    function extractPageData(timeLabel) {
        const ths = document.querySelectorAll('thead tr[data-testid="beast-core-table-header-tr"] th');
        let headers = [];
        ths.forEach((th) => {
            let text = th.innerText.replace(/\n/g, '').trim();
            if (text.includes("操作")) headers.push({ name: "operation", type: "ignore" });
            else if (text.includes("商品信息")) headers.push({ name: "product_info", type: "info" });
            else headers.push({ name: text, type: "metric" });
        });

        const rows = document.querySelectorAll('tr[data-testid="beast-core-table-body-tr"]');
        let pageList = [];

        rows.forEach((row) => {
            let rowData = { "meta_time_label": timeLabel };
            const tds = row.querySelectorAll('td[data-testid="beast-core-table-td"]');
            
            tds.forEach((td, colIndex) => {
                if (colIndex >= headers.length) return;
                const header = headers[colIndex];

                if (header.type === "info") {
                    try {
                        let titleEl = td.querySelector('.beast-core-ellipsis-1');
                        rowData["商品名称"] = titleEl ? titleEl.innerText.trim() : "未知标题";
                        let idText = td.innerText.match(/ID:(\d+)/);
                        rowData["商品ID"] = idText ? idText[1] : "未知ID";
                    } catch (e) {}
                } else if (header.type === "metric") {
                    try {
                        let mainValEl = td.querySelector('div[class*="list_value__"]');
                        let subValEl = td.querySelector('div[class*="list_ratioValue__"]');
                        let subText = "";
                        
                        if (subValEl) {
                            let clone = subValEl.cloneNode(true);

                            // 1. 查找前缀元素 (如"较前1日")
                            // 关键修改:去掉了后面的空格,让它紧贴趋势词
                            let prefixEl = clone.querySelector('.radio-indicator-item_radioPrefix__zh8iy');
                            let hasPrefix = false;
                            if (prefixEl) {
                                hasPrefix = true;
                                prefixEl.innerText = prefixEl.innerText.trim(); // 去空格
                            }

                            // 2. 查找并替换箭头
                            let hasArrow = false;
                            
                            let downSvg = clone.querySelector('svg[data-testid="beast-core-icon-arrow-down_filled"]');
                            if (downSvg) {
                                hasArrow = true;
                                // "下降 " (带空格,分隔数值)
                                downSvg.parentNode.replaceChild(document.createTextNode("下降 "), downSvg);
                            }

                            let upSvg = clone.querySelector('svg[data-testid="beast-core-icon-arrow-up_filled"]');
                            if (upSvg) {
                                hasArrow = true;
                                // "上涨 " (带空格,分隔数值)
                                upSvg.parentNode.replaceChild(document.createTextNode("上涨 "), upSvg);
                            }

                            // 3. 处理"持平"逻辑
                            // 如果有前缀(较前1日),但没有箭头,说明是持平
                            // 不管数值是 0 还是 0%,统一处理
                            if (hasPrefix && !hasArrow) {
                                // 在前缀后面强制插入 "持平 "
                                let flatText = document.createTextNode("持平 ");
                                prefixEl.after(flatText);
                            }

                            // 4. 提取最终文本
                            // 此时结构应该是: "较前1日" + "下降 " + "28%"
                            // 或者: "较前1日" + "持平 " + "0"
                            let rawText = clone.innerText.replace(/\n/g, '').trim();
                            
                            // 5. 最终清洗:将多个空格合并为1个,确保 split 正常
                            subText = rawText.replace(/\s+/g, ' ').trim();
                        }
                        
                        rowData[header.name + "_主"] = mainValEl ? mainValEl.innerText.replace(/\n/g, '').trim() : "";
                        rowData[header.name + "_副"] = subText;
                    } catch (e) {}
                }
            });
            if (Object.keys(rowData).length > 0) pageList.push(rowData);
        });
        return pageList;
    }

    // 4. 下载逻辑
    function downloadAll(finalList, fontUrl, baseFileName) {
        function triggerDownload(content, fileName, mimeType) {
            const blob = (content instanceof Blob) ? content : new Blob([content], { type: mimeType });
            const link = document.createElement("a");
            link.href = URL.createObjectURL(blob);
            link.download = fileName;
            link.style.display = 'none';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }

        console.log(`✅ 采集完成!文件名: ${baseFileName}.json`);
        
        if (fontUrl) {
            fetch(fontUrl)
                .then(res => res.blob())
                .then(blob => {
                    triggerDownload(blob, 'font.ttf', 'font/ttf');
                    setTimeout(() => {
                        const jsonContent = JSON.stringify(finalList, null, 2);
                        triggerDownload(jsonContent, `${baseFileName}.json`, 'application/json');
                    }, 1000);
                }).catch(() => {
                    const jsonContent = JSON.stringify(finalList, null, 2);
                    triggerDownload(jsonContent, `${baseFileName}.json`, 'application/json');
                });
        } else {
            const jsonContent = JSON.stringify(finalList, null, 2);
            triggerDownload(jsonContent, `${baseFileName}.json`, 'application/json');
        }
    }

    // === 主流程 ===
    let fontUrl = null;
    const styles = document.querySelectorAll('style');
    for (let style of styles) {
        if (style.innerHTML.includes('spider-font') && style.innerHTML.includes('.ttf')) {
            const match = style.innerHTML.match(/url\(['"]?(.*?)['"]?\)/);
            if (match && match[1]) {
                fontUrl = match[1];
                if (fontUrl.startsWith('//')) fontUrl = 'https:' + fontUrl;
                break;
            }
        }
    }

    const finalFileName = getFileNameMeta();
    console.log("目标文件名:", finalFileName);

    const mode = prompt(`文件名: ${finalFileName}.json\n\n模式:\n1 = 仅当前页\nall = 翻页采集所有`, "1");
    if (!mode) return;

    const timeLabel = getActiveTimeLabel();
    let allData = [];

    if (mode === '1') {
        allData = extractPageData(timeLabel);
        downloadAll(allData, fontUrl, finalFileName);
    } else if (mode === 'all') {
        let pageNum = 1;
        while (true) {
            console.log(`正在采集第 ${pageNum} 页...`);
            const pageData = extractPageData(timeLabel);
            if (pageData.length === 0) { console.warn("空数据停止"); break; }
            allData.push(...pageData);

            const nextBtn = document.querySelector(NEXT_PAGE_SELECTOR);
            if (!nextBtn) break;
            let isDisabled = false;
            for (let cls of nextBtn.classList) {
                if (cls.includes("PGT_disabled")) { isDisabled = true; break; }
            }
            if (isDisabled) { console.log("翻页结束"); break; }

            nextBtn.click();
            pageNum++;
            await sleep(WAIT_TIME);
        }
        downloadAll(allData, fontUrl, finalFileName);
    }
})();