阿里巴巴国际站访客详情采集导出--树洞先生

采集阿里巴巴访客详情并导出,可根据页面选择的日期

// ==UserScript==
// @name         阿里巴巴国际站访客详情采集导出--树洞先生
// @namespace    http://tampermonkey.net/
// @version      1.0
// @license      MIT
// @description  采集阿里巴巴访客详情并导出,可根据页面选择的日期
// @author       树洞先生
// @match        https://data.alibaba.com/marketing/visitor*
// @match        https://mydata.alibaba.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 字段映射
    const FIELD_MAP = {
        'visitorId':'访客ID',
        'buyerName':'访客姓名',
        'buyerCountry':'访客国家',
        'buyerRegion':'访客国家区域',
        'statDate':'进店日期',
        'isGoldBuyer':'金标买家',
        'levelTag':'访客等级',
        'isBrandFansBuyer':'品牌粉丝',
        'buyerTag':'标签',
        'isOnlineRetailerBuyer':'电商买家',
        'searchKeyword':'进店关键词',
        'serKeywords':'全站偏好关键词',
        'staySecond':'停留时长',
        'visitPv':'浏览次数',
        'isMcFb':'是否发起了询盘',
        'isAtmFb':'是否发起了TM',
        'isVisitHomepage':'是否访问了主页',
        'isVisitProfilePage':'是否访问了店铺资料主页',
        'isVisitContactPage':'是否访问了联系页面',
        'isViewContactInformation':'是否查看了联系人信息',
        'isClickPlaceOrder':'点击了提交订单',
        'isVisitCertifiedInfo':'浏览证书信息',
        'sendEmailCnt':'发送邮件数量',
        'totalVisitPv':'总浏览量',
        'totalVisitSellerCnt':'浏览供应商数量',
        'totalRfqCnt':'发布RFQ数量',
        'totalMcFbCnt':'对多少个供应商发起了多少个询盘',
        'totalMcSellerCnt':'对多少个供应商发起了多少个TM'
    };

    const header = Object.values(FIELD_MAP);
    const requiredFields = Object.keys(FIELD_MAP);

    // 采集参数
    const pageSize = 10;

    // 获取 cookie
    function getCookie(name) {
        let matches = document.cookie.match(new RegExp(
            "(?:^|; )" + name.replace(/([.$?*|{}()\[\]\\/+^])/g, '\\$1') + "=([^;]*)"
        ));
        return matches ? decodeURIComponent(matches[1]) : undefined;
    }

    // 动态获取 dmtrack_pageid
    function getDmtrackPageId() {
        const match = document.cookie.match(/dmtrack_pageid=([^;]+)/);
        if (match) return match[1];
        if (window.dmtrack && window.dmtrack.pageid) return window.dmtrack.pageid;
        if (localStorage.getItem('dmtrack_pageid')) return localStorage.getItem('dmtrack_pageid');
        return Math.random().toString().slice(2) + Date.now();
    }

    // 引入SheetJS(xlsx)库
    const script = document.createElement('script');
    script.src = 'https://cdn.sheetjs.com/xlsx-0.20.3/package/dist/xlsx.full.min.js';
    script.onload = () => { window.XLSX_READY = true; };
    document.head.appendChild(script);

    // 获取采集日期(从页面)
    function getDateRangeFromPage() {
        const dateDiv = document.querySelector('#J-common-state-text');
        if (dateDiv) {
            return {
                startDate: dateDiv.getAttribute('data-startdate') || '',
                endDate: dateDiv.getAttribute('data-enddate') || ''
            };
        }
        return { startDate: '', endDate: '' };
    }

    // 修改getVisitorData函数,支持传入startDate和endDate
    async function getVisitorData(pageNo, startDate, endDate) {
        const ctoken = '103hhn0vs58nu';
        const dmtrack_pageid = '6797ac192102fef51750650324';
        const xsrfToken = '717f8886-87b1-4bd1-aee0-dd98d2585668';
        const url = `https://mydata.alibaba.com/self/.json?action=CommonAction&iName=getVisitors&isVip=true&0.686084886315589&ctoken=${ctoken}&dmtrack_pageid=${dmtrack_pageid}`;
        const data = new URLSearchParams({
            orderBy: '',
            orderModel: '',
            pageSize: '10',
            pageNO: String(pageNo),
            statisticsType: 'day',
            selected: '0',
            startDate: startDate || '',
            endDate: endDate || '',
            searchKeyword: '',
            buyerRegion: '',
            buyerCountry: '',
            subMemberSeq: '',
            isMcFb: 'false',
            isAtmFb: 'false',
            hasRemarks: 'false',
            statisticType: 'os',
            desTime: String(Date.now())
        });

        const res = await fetch(url, {
            method: 'POST',
            headers: {
                'accept': 'application/json',
                'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
                'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'x-xsrf-token': xsrfToken
            },
            body: data,
            credentials: 'include'
        });
        const text = await res.text();
        console.log('接口返回内容:', text);
        return JSON.parse(text);
    }

    // 便于控制台直接调试fetch请求
    window.runVisitorExport = getVisitorData;

    // 导出为Excel xlsx
    function exportToXLSX(rows, filename = '访客详情.xlsx') {
        if (!window.XLSX_READY) {
            alert('Excel导出库加载中,请稍后再试');
            return;
        }
        // 组装二维数组,第一行为表头
        const aoa = [header, ...rows.map(row => header.map(h => row[h] ?? ''))];
        const ws = XLSX.utils.aoa_to_sheet(aoa);
        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, '访客详情');
        XLSX.writeFile(wb, filename);
    }

    // 页面添加按钮和进度条
    function addButton() {
        const btn = document.createElement('button');
        btn.textContent = '采集访客详情并导出-树洞先生';
        btn.style.position = 'fixed';
        btn.style.top = '100px';
        btn.style.right = '40px';
        btn.style.zIndex = 9999;
        btn.onclick = main;
        document.body.appendChild(btn);

        // 添加进度显示元素
        const progressDiv = document.createElement('div');
        progressDiv.id = 'visitor-progress';
        progressDiv.style.position = 'fixed';
        progressDiv.style.top = '140px';
        progressDiv.style.right = '40px';
        progressDiv.style.zIndex = 9999;
        progressDiv.style.background = 'rgba(255,255,255,0.95)';
        progressDiv.style.padding = '8px 16px';
        progressDiv.style.border = '1px solid #ccc';
        progressDiv.style.borderRadius = '4px';
        progressDiv.style.fontSize = '14px';
        progressDiv.style.display = 'none';
        document.body.appendChild(progressDiv);
    }

    // 主函数
    async function main() {
        alert('开始采集访客详情,完成后自动下载Excel文件');
        // 动态获取采集日期
        const { startDate, endDate } = getDateRangeFromPage();
        if (!startDate || !endDate) {
            alert('未能从页面获取采集日期,请先在页面选择日期');
            return;
        }
        // 先获取总数
        const firstPage = await getVisitorData(1, startDate, endDate);
        if (!firstPage.value || !firstPage.value.total) {
            alert('获取数据失败');
            return;
        }
        const total = firstPage.value.total;
        const totalPages = Math.ceil(total / pageSize);
        let allVisitors = [];

        // 显示进度条
        const progressDiv = document.getElementById('visitor-progress');
        progressDiv.style.display = 'block';
        progressDiv.textContent = `采集进度:0/${total} (0%)`;

        // 并发采集所有页面,并实时更新进度
        let completed = 0;
        let allPages = [];
        for (let i = 1; i <= totalPages; i++) {
            allPages.push(
                getVisitorData(i, startDate, endDate).then(page => {
                    console.log(`第${i}页数据:`, page.value && page.value.data);
                    completed += (page.value && page.value.data ? page.value.data.length : 0);
                    progressDiv.textContent = `采集进度:${completed}/${total} (${Math.min(100, Math.round(completed/total*100))}%)`;
                    return page;
                })
            );
        }
        const pages = await Promise.all(allPages);

        for (const page of pages) {
            if (page.value && page.value.data) {
                for (const visitor of page.value.data) {
                    // 映射字段
                    let row = {};
                    for (const [en, cn] of Object.entries(FIELD_MAP)) {
                        row[cn] = visitor[en] ?? '';
                    }
                    allVisitors.push(row);
                }
            }
        }
        console.log('全部采集完成,allVisitors长度:', allVisitors.length);
        console.log('allVisitors内容:', allVisitors);
        console.log('准备导出Excel...');
        // 拼接文件名
        const fileName = `访客详情_${startDate}_${endDate}.xlsx`;
        exportToXLSX(allVisitors, fileName);
        console.log('Excel导出完成');
        progressDiv.textContent = `采集完成,已采集 ${allVisitors.length} 条,Excel已下载`;
        setTimeout(() => { progressDiv.style.display = 'none'; }, 5000);
        alert('采集完成,Excel已下载');
    }

    addButton();
})();

QingJ © 2025

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