user459
(飞过山)
1
我写了个油猴脚本
已经指定
@run-at document-start
但是发现 想通过以下方法拦截请求时,还是一些请求比我的脚本更快。这是什么原因呢?
const originalXhrOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url, ...rest) {
return originalXhrOpen.apply(this, [method, url, ...rest]);
};
3 个赞
anghunk
(神奇的哆啦z梦)
2
油猴肯定后于网站加载,点击事件可以拦截,默认加载的接口一般拦截不掉吧
user459
(飞过山)
3
我想获取淘宝/天猫当前页面的商品信息,虽然淘宝天猫都有/mtop.taobao.pcdetail.data.get/1.0/
这个请求,但是发现天猫的请求比我脚本更快。目前只能抓到淘宝的,抓不到天猫的。
完整代码如下:
// ==UserScript==
// @name Taobao 信息获取
// @namespace http://tampermonkey.net/
// @version 1.2
// @description 获取商品信息
// @match https://item.taobao.com/*
// @match https://detail.tmall.com/*
// @grant none
// @run-at document-start
// ==/UserScript==
(function () {
'use strict';
let productPriceInfo = ''; // 用于存储产品价格信息的变量
// 处理 Taobao 数据的函数
function processTaobaoData(taobao) {
try {
const skuInfo = taobao.data.skuCore.sku2info;
const skus = taobao.data.skuBase.skus;
const props = taobao.data.skuBase.props;
skus.forEach(sku => {
const skuId = sku.skuId;
const propPaths = sku.propPath.split(';');
let productDetails = [];
// 遍历 propPaths 数组,匹配每一个 propPath
propPaths.forEach(propPath => {
const [pid, vid] = propPath.split(':');
const prop = props.find(p => p.pid === pid);
if (prop) {
const value = prop.values.find(v => v.vid === vid);
if (value) {
productDetails.push({
propName: prop.name,
valueName: value.name,
});
}
}
});
if (skuInfo[skuId]) {
let priceText = skuInfo[skuId].price.priceText
const subPrice = skuInfo[skuId].subPrice
if (subPrice) {
priceText = subPrice.priceText;
}
let detailText = ""
productDetails.forEach(detail => {
detailText += `${detail.propName}: ${detail.valueName} \t`
});
console.log(`SKU ID: ${skuId}, Price: ${priceText}, Details: ${detailText}`);
productPriceInfo += `${skuId}\t${priceText}\t${detailText}\n`;
}
});
addCopyButton(); // 解析完成后添加按钮
} catch (error) {
console.error('Error processing Taobao data:', error);
}
}
function addCopyButton() {
// 创建按钮
const copyButton = document.createElement('button');
copyButton.innerText = '复制商品价格';
copyButton.style.position = 'fixed';
copyButton.style.right = '20px';
copyButton.style.top = '50%';
copyButton.style.fontSize = '40px';
copyButton.style.transform = 'translateY(-50%)';
copyButton.style.padding = '10px 20px';
copyButton.style.backgroundColor = '#ff5000';
copyButton.style.color = '#fff';
copyButton.style.border = 'none';
copyButton.style.borderRadius = '5px';
copyButton.style.cursor = 'pointer';
copyButton.style.zIndex = '1000';
// 将按钮添加到页面
document.body.appendChild(copyButton);
// 绑定点击事件,复制内容到剪贴板
copyButton.addEventListener('click', () => {
if (productPriceInfo) {
navigator.clipboard.writeText(productPriceInfo).then(() => {
// 修改按钮文字提示用户已复制成功
const originalText = copyButton.innerText;
copyButton.innerText = '复制成功!';
// 1 秒后恢复按钮原始文字
setTimeout(() => {
copyButton.innerText = originalText;
}, 1000);
}, () => {
copyButton.innerText = '复制失败';
setTimeout(() => {
copyButton.innerText = '复制商品价格';
}, 1000);
});
} else {
copyButton.innerText = '无可复制内容';
setTimeout(() => {
copyButton.innerText = '复制商品价格';
}, 1000);
}
});
}
// 拦截请求并处理数据
const originalXhrOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (method, url, ...rest) {
if (url.includes('/mtop.taobao.pcdetail.data.get/1.0/')) {
this.addEventListener('load', function () {
if (this.readyState === 4 && this.status === 200) {
try {
const response = JSON.parse(this.responseText);
processTaobaoData(response);
} catch (e) {
console.error('Failed to parse Taobao response:', e);
}
}
});
}
return originalXhrOpen.apply(this, [method, url, ...rest]);
};
})();
user459
(飞过山)
4
不是的,有个指定的方法是 document-start ,我 debug 的调试的时候发现我的脚本加载的时间是比页面靠前的,但是XMLHttpRequest内的拦截却滞后。
已经知道原因了,因为天猫的这个请求使用的在 js 中的(jsoup)。
但是淘宝属于 api 请求(XMLHttpRequest)
目前无法 hook 到 js 文件的加载,所以暂时无法 hook 到天猫的数据。
clenhg
(clen)
5
道高一尺魔高一丈
function log(func) {
return function() {
console.log(arguments);
return func.apply(this, arguments);
};
}
let __mtopjsonp1;
Object.defineProperty(window, 'mtopjsonp1', {
get: function () {
return __mtopjsonp1;
},
set: function (mtopjsonp1) {
__mtopjsonp1 = log(mtopjsonp1);
}
});
1 个赞