您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
1.使得点击【登录复制】后可以直接复制,而不用登录; 2.设置整个页面的文本为可选的以及复制。
// ==UserScript== // @name 拼多多商品数据获取 // @namespace http://tampermonkey.net/ // @version 2024-05-34 // @description 1.使得点击【登录复制】后可以直接复制,而不用登录; 2.设置整个页面的文本为可选的以及复制。 // @author 逃逸线 // @match *://mms.pinduoduo.com/goods/goods_list* // @icon https://www.google.com/s2/favicons?sz=64&domain=pinduoduo.com // @grant GM_xmlhttpRequest // @grant GM_download // @grant GM_addStyle // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/xlsx.full.min.js // @license MIT // @description 1.使得点击【登录复制】后可以直接复制,而不用登录; 2.设置整个页面的文本为可选的以及复制。 // ==/UserScript== (function() { 'use strict'; let dataList = []; let dataDetail=[]; function waitForElement(selector, callback) { var element = document.querySelector(selector); if (element) { callback(element); } else { setTimeout(function() { waitForElement(selector, callback); }, 500); } } // 尝试等页面元素加载完成 waitForElement('.batch_operate_batchOperate__1mERa', function(element) { // 找到元素后执行您的操作 return createBtn() }); function createBtn(){ // 创建按钮元素 var button = document.createElement('button') button.textContent = '下载数据(最大数<30),请先进行筛选,确保不超过30条,刷新请按 F5。'; button.id = 'downloadButton'; // 设置按钮样式 button.style.padding = '10px'; button.style.backgroundColor = '#3498db'; button.style.color = '#ffffff'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.cursor = 'pointer'; button.disabled=false var element = document.querySelector('.batch_operate_batchOperate__1mERa'); element.appendChild(button); //插入按钮 // 添加点击事件处理程序 button.addEventListener('click', function() { dataList = []; var button = document.getElementById('downloadButton'); button.disabled=true button.textContent='请求获取中...' button.style.backgroundColor = '#056b00'; // 经常会变化 var bottomPGT = document.querySelector('.TB_bottom_5-119-0'); console.log("111111111111") var pageNum=bottomPGT.querySelector('[data-testid="beast-core-select-htmlInput"]') // 创建点击事件 var clikeEvent = new MouseEvent('click', { bubbles: true, cancelable: true }); pageNum.dispatchEvent(clikeEvent) //模拟点击页码 弹出下拉选择 // var dropdown = document.querySelector('.ST_dropdownPanel_5-116-0 '); //下拉组件 // var lastChild = dropdown.lastElementChild; // lastChild.dispatchEvent(clikeEvent) setTimeout(() => getList(), 2000); }); } async function getList(){ var rows = document.querySelectorAll('[data-testid="beast-core-table-body-tr"]'); //获取表格里的每一行数据 let i = 0; for (let i = 0; i < rows.length; i++) { var row=rows[i] var tds= row.querySelectorAll('[data-testid="beast-core-table-td"]'); var id= row.querySelector('.goods-id').children[0].textContent;//商品id await getDeatil(id) await new Promise(resolve => setTimeout(resolve, 5000)); // 延迟5秒后处理下一个商品 var pic=row.querySelector('img').src////商品图片 var goodsName=row.querySelector('.goods-name').textContent//商品标题 var sumSales=tds[4].children[0].textContent var thirtySales=tds[5].children[0].textContent var createText=tds[7].textContent var createTime var operator var datetimeRegex = /(\d{4}-\d{2}-\d{2} \d{2}:\d{2})/; var match = createText.match(datetimeRegex); // var operatorText =row.querySelector('[data-testid="beast-core-box"]').children[0].children[0].querySelector('span').textContent // 检查字符串中是否包含 ':' // if (operatorText.split(':').length>1) { // operator = operatorText.split(':')[1].trim(); // } else { // 如果不包含 ':',直接使用整个文本内容 // operator = operatorText.trim(); // } if (match) { createTime = match[1]; // 提取匹配到的时间部分 } let obj={} obj.链接标题=goodsName obj.商品id=id // obj.运营人员=operator obj.商品图片=pic obj.三十天销量=thirtySales obj.总销量=sumSales obj.上架时间=createTime obj.商品链接="https://mobile.yangkeduo.com/goods.html?goods_id="+id dataList.push(obj) }; console.log(dataList) console.log(dataDetail) var next = document.querySelector('[data-testid="beast-core-pagination-next"]'); // 获取下一页按钮 如果没有下一页终止递归 导出表格 if(dataList.length>29){ next=null } if(!next||next.classList.contains("PGT_disabled_5-119-0")){ download(dataList,dataDetail) } else if(next.classList.contains("PGT_next_5-119-0")){ // 创建点击事件 var clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, }); // 触发点击事件 next.dispatchEvent(clickEvent); var delay = Math.floor(Math.random() * (1000 + 1)) + 500; // 做延迟处理 防止请求过快风控 setTimeout(() => getList(), delay); } else{ alert('脚本出错,请检查!!!') } } async function getDeatil(goods_id){ // 异步请求的具体实现 return new Promise(resolve => { // 异步操作... // 在操作完成后调用 resolve var detailUrl = 'https://mms.pinduoduo.com/goods/goods_detail?goods_id='+goods_id+'&page_num=12'; var newTab = window.open(detailUrl, '_blank'); if (newTab) { newTab.onload = async function() { await new Promise(resolve => setTimeout(resolve, 2000)); // 等待一段时间确保页面加载完全(可根据实际情况调整) var trs=newTab.document.querySelectorAll('[data-testid="beast-core-table-th"]'); var guigeSize var trTitle={} for(var i=0; i<trs.length ;i++){ if(trs[i].children[0].textContent=='库存'){ guigeSize=i } var titleText = trs[i].children[0].textContent.trim(); // 获取标题文本并去除首尾空格 if(titleText=="拼单价(元)"){ trTitle['拼单价'] = i } else if(titleText=="单买价(元)"){ trTitle['单买价'] = i } else{ trTitle[titleText] = i; // 将标题文本作为键,列索引 i 作为值存储到对象中 } } // 提取详情页中的内容 var rows = newTab.document.querySelectorAll('[data-testid="beast-core-table-body-tr"]'); let rowspan let rowIndex for (let i = 0; i < rows.length; i++) { var rowSpan= rows[i].querySelectorAll('[data-testid="beast-core-table-td"]')[0]; if(rowSpan.getAttribute('rowspan')>1){ rowspan=rowSpan.getAttribute('rowspan') var curSpan=rowSpan rowIndex=i rowSpan.setAttribute('rowspan',1) curSpan.setAttribute('rowspan',1) } let row=rows[i] var tds= row.querySelectorAll('[data-testid="beast-core-table-td"]'); if(rowspan>1&&i!=rowIndex){ var parentElement = tds[0].parentNode; // 获取第一个 td 元素的父节点 // 复制第一个节点的数据 var clonedNode = curSpan.cloneNode(true); // 在第一个节点之前插入复制的节点 parentElement.insertBefore(clonedNode, tds[0]); tds= row.querySelectorAll('[data-testid="beast-core-table-td"]'); } var skuName var promotionPrice var unitPrice var purchasePrice var code var img if(guigeSize==1){ skuName=tds[0].children[0].textContent }else{ skuName=tds[0].children[0].textContent+tds[1].children[0].textContent } if(trTitle.活动价){ promotionPrice=tds[trTitle.活动价].textContent } unitPrice=tds[trTitle.拼单价].textContent purchasePrice=tds[trTitle.单买价].textContent code=tds[trTitle.规格编码].textContent img=tds[trTitle.规格预览图].querySelector('img').src let obj={} obj.商品id=goods_id obj.sku名称=skuName obj.活动价=promotionPrice obj.拼单价=unitPrice obj.单买价=purchasePrice obj.规格编码=code obj.sku图片=img dataDetail.push(obj) } // 处理详情页内容,例如输出到控制台 // 关闭新标签页 newTab.close(); }; } resolve(); }); } function download(dataList, dataDetail) { function exportToExcel(data, sheetName,nullHeader) { var headers = Object.keys(data[0]); headers = headers.concat(nullHeader); var rows = data.map(obj => { var row = headers.map(header => { if (Array.isArray(nullHeader) && nullHeader.includes(header)) { return ''; // 空白值 } else { return obj[header]; } }); return row; }); var workbook = XLSX.utils.book_new(); var worksheet = XLSX.utils.aoa_to_sheet([headers].concat(rows)); XLSX.utils.book_append_sheet(workbook, worksheet, sheetName); var xlsxData = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); var blob = new Blob([xlsxData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); var link = document.createElement('a'); link.href = window.URL.createObjectURL(blob); var today = new Date(); var formattedDate = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate(); link.download = 'PDD' +formattedDate+ sheetName + '.xlsx'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } var dataListNullHeader=["款式编码","保本投产比","预设投产比","前置利润率","运营人员"] var dataDetailNullHeader=["利润率"] exportToExcel(dataList, '商品数据',dataListNullHeader); exportToExcel(dataDetail, 'sku数据',dataDetailNullHeader); var button = document.getElementById('downloadButton'); button.disabled = false; button.textContent = '下载数据(最大数<30),请先进行筛选,确保不超过30条,刷新请按 F5。'; button.style.backgroundColor = '#3498db'; } })();