来论坛这么久了,一直在白嫖论坛的资源,也希望能够做一些力所能及的贡献。
之前在各大AI站这个帖子中,见到有老哥提出可以将ip-checker这个油猴脚本改一改,让它批量检测ip质量。我就糊了一个非常简易的版本,简易到甚至要用控制台来输出,但意思应该是到了。
下面是代码:
// ==UserScript==
// @name ip-checker
// @namespace http://tampermonkey.net/
// @version 1.4
// @description 显示当前使用的公网IP地址,并带有折叠展开功能和刷新功能,以及IP风险查询功能
// @author https://linux.do/u/snaily
// @match http://*/*
// @match https://*/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @connect api.ipify.org
// @connect api64.ipify.org
// @connect ip-api.com
// @connect scamalytics.com
// @connect ping0.cc
// @connect talosintelligence.com
// @license MIT
// ==/UserScript==
(function() {
'use strict';
let OutputLog = {};
let NoOuputLogFlag = true;
let TotalIPs = [];
const WaitingSec = 10;
const Ping0PassScore = 10;
const ScamalyticsPassScore = 10;
OutputLog.err = function(msg)
{
if(NoOuputLogFlag) return;
console.error(msg);
};
OutputLog.log = function(msg)
{
if(NoOuputLogFlag) return;
console.log(msg);
};
OutputLog.must = function(msg)
{
console.log(msg);
};
async function fetchCurrentIP() {
OutputLog.log('Fetching current IP...');
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = true;
refreshButton.innerHTML = '正在刷新...';
}
var textArea = document.getElementById('ipListInputTextArea');
let ipText = textArea.value;
let ips = ipText.split('\n');
TotalIPs = ips;
while(TotalIPs.length > 0)
{
let ip = TotalIPs.shift();
fetchIPDetails(ip, null);
await new Promise(resolve => setTimeout(resolve, WaitingSec * 1000));
}
alert('All IPs have been fetched!');
}
function isIPv6(ip) {
// IPv6正则表达式
const ipv6Pattern = new RegExp('^([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})$|^:((:[0-9a-fA-F]{1,4}){1,7}|:)$|^fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}$|^::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])$|^([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9])?[0-9])$');
return ipv6Pattern.test(ip);
}
function fetchIPDetails(ip,ipv6) {
OutputLog.log('Fetching IP details for:', ip);
OutputLog.log(ipv6);
GM_xmlhttpRequest({
method: "GET",
url: "http://ip-api.com/json/" + ip,
onload: function(response) {
OutputLog.log('IP details fetched:', response.responseText);
const ipDetails = JSON.parse(response.responseText);
fetchIPRisk(ip,ipv6,ipDetails);
},
onerror: function(error) {
OutputLog.log('Error fetching IP details:', error);
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = false;
refreshButton.innerHTML = '点击刷新IP信息';
}
}
});
}
function fetchIPRisk(ip,ipv6,details) {
OutputLog.log('Fetching IP risk for:', ip);
OutputLog.log(ipv6);
GM_xmlhttpRequest({
method: "GET",
url: `https://scamalytics.com/ip/${ip}`,
onload: function(response) {
OutputLog.log('IP risk fetched:', response.responseText);
const riskData = parseIPRisk(response.responseText);
fetchPing0Risk(ip,ipv6,details, riskData);
},
onerror: function(error) {
TotalIPs.push(ip);
OutputLog.log('Error fetching IP risk:', error);
displayIPDetails(ipv6,details, null, null);
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = false;
refreshButton.innerHTML = '点击刷新IP信息';
}
}
});
}
function fetchPing0Risk(ip,ipv6, details, riskData)
{
OutputLog.log('Fetching Ping0 risk for:', ip);
OutputLog.log(ipv6);
GM_xmlhttpRequest({
method: "GET",
url: `https://ping0.cc/ip/${ip}`,
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36"
},
onload: function(response) {
OutputLog.log('Initial Ping0 response:' + response.responseText);
const windowX = parseWindowX(response.responseText);
if (windowX) {
OutputLog.log('Parsed window.x value:', windowX);
GM_xmlhttpRequest({
method: "GET",
url: `https://ping0.cc/ip/${ip}`,
headers: {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
"Cookie": `jskey=${windowX}`
},
onload: function(response) {
OutputLog.log('Final Ping0 response:' + response.responseText);
const ping0Data = parsePing0Risk(response.responseText);
displayIPDetails(ipv6,details, riskData, ping0Data);
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = false;
refreshButton.innerHTML = '点击刷新IP信息';
}
},
onerror: function(error) {
OutputLog.log('Error fetching final Ping0 risk:', error);
displayIPDetails(ipv6,details, riskData, null);
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = false;
refreshButton.innerHTML = '点击刷新IP信息';
}
}
});
} else {
TotalIPs.push(ip);
OutputLog.log('Failed to retrieve window.x value.');
displayIPDetails(ipv6,details, riskData, null);
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = false;
refreshButton.innerHTML = '点击刷新IP信息';
}
}
},
onerror: function(error) {
OutputLog.log('Error fetching initial Ping0 page:', error);
displayIPDetails(ipv6,details, riskData, null);
const refreshButton = document.getElementById('refreshIpInfo');
if (refreshButton) {
refreshButton.disabled = false;
refreshButton.innerHTML = '点击刷新IP信息';
}
}
});
}
function parseIPRisk(html) {
OutputLog.log('Parsing IP risk data...');
const scoreMatch = html.match(/"score":"(.*?)"/);
const riskMatch = html.match(/"risk":"(.*?)"/);
if (riskMatch) {
const riskData = {
score: scoreMatch[1],
risk: riskMatch[1]
};
OutputLog.log('Parsed risk data:', riskData);
return riskData;
}
OutputLog.log('Failed to parse risk data.');
return null;
}
function parseWindowX(html) {
OutputLog.log('Parsing window.x value...');
const match = html.match(/window\.x\s*=\s*'([^']+)'/);
const windowX = match ? match[1] : null;
OutputLog.log('Parsed window.x:', windowX);
return windowX;
}
function parsePing0Risk(html) {
OutputLog.log('Parsing Ping0 risk data...');
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const riskValue = doc.evaluate('/html/body/div[2]/div[2]/div[1]/div[2]/div[9]/div[2]/span', doc, null, XPathResult.STRING_TYPE, null).stringValue;
const ipType = doc.evaluate('/html/body/div[2]/div[2]/div[1]/div[2]/div[8]/div[2]/span', doc, null, XPathResult.STRING_TYPE, null).stringValue;
const nativeIP = doc.evaluate('/html/body/div[2]/div[2]/div[1]/div[2]/div[11]/div[2]/span', doc, null, XPathResult.STRING_TYPE, null).stringValue;
const ping0Data = {
riskValue: riskValue.trim(),
ipType: ipType.trim(),
nativeIP: nativeIP.trim()
};
OutputLog.log('Parsed Ping0 data:', ping0Data);
return ping0Data;
}
function displayIPDetails(ipv6,details, riskData, ping0Data) {
OutputLog.log('Displaying IP details...');
var ipElement = document.getElementById('ipInfo');
if (!ipElement) {
ipElement = document.createElement('div');
ipElement.id = 'ipInfo';
ipElement.style.position = 'fixed';
ipElement.style.top = GM_getValue('ipInfoTop', '10px');
ipElement.style.right = '-500px';
ipElement.style.backgroundColor = '#fff';
ipElement.style.padding = '10px';
ipElement.style.borderRadius = '5px 0 0 5px'; // 仅左侧有圆角
ipElement.style.boxShadow = '0 0 10px rgba(0,0,0,0.1)';
ipElement.style.fontSize = '14px';
ipElement.style.color = '#333';
ipElement.style.zIndex = '9999';
ipElement.style.transition = 'right 0.3s ease'; // 添加平滑过渡效果
const title = document.createElement('div');
title.style.fontWeight = 'bold';
title.style.marginBottom = '5px';
title.innerText = 'IP检测信息';
const refreshButton = document.createElement('button');
refreshButton.id = 'refreshIpInfo';
refreshButton.style.display = 'inline-block';
refreshButton.style.width = 'auto';
refreshButton.style.marginLeft = '10px';
refreshButton.style.backgroundColor = '#007bff';
refreshButton.style.color = '#fff';
refreshButton.style.border = 'none';
refreshButton.style.borderRadius = '3px';
refreshButton.style.padding = '2px 5px';
refreshButton.style.cursor = 'pointer';
refreshButton.style.fontSize = '12px';
refreshButton.innerHTML = '刷新IP信息';
refreshButton.onclick = fetchCurrentIP;
const toggleButton = document.createElement('button');
toggleButton.id = 'toggleIpInfo';
toggleButton.style.display = 'none';
toggleButton.style.width = 'auto';
toggleButton.style.marginLeft = '10px';
toggleButton.style.backgroundColor = '#007bff';
toggleButton.style.color = '#fff';
toggleButton.style.border = 'none';
toggleButton.style.borderRadius = '3px';
toggleButton.style.padding = '2px 5px';
toggleButton.style.cursor = 'pointer';
toggleButton.style.fontSize = '12px';
toggleButton.innerHTML = '展开信息';
toggleButton.onclick = toggleIpInfo;
const dragHandle = document.createElement('div');
dragHandle.style.width = '100%';
dragHandle.style.height = '10px';
dragHandle.style.backgroundColor = '#ccc';
dragHandle.style.cursor = 'move';
dragHandle.style.marginBottom = '10px';
dragHandle.onmousedown = startDragging;
const content = document.createElement('div');
content.id = 'ipInfoContent';
title.appendChild(refreshButton);
title.appendChild(toggleButton);
ipElement.appendChild(title);
ipElement.appendChild(dragHandle);
ipElement.appendChild(content);
document.body.appendChild(ipElement);
// 创建展开按钮
const expandButton = document.createElement('button');
expandButton.id = 'expandIpInfo';
expandButton.style.position = 'fixed';
expandButton.style.top = GM_getValue('ipInfoTop', '10px');
expandButton.style.width = 'auto';
expandButton.style.right = '0';
expandButton.style.backgroundColor = '#007bff';
expandButton.style.color = '#fff';
expandButton.style.border = 'none';
expandButton.style.borderRadius = '3px 0 0 3px';
expandButton.style.padding = '2px 5px';
expandButton.style.cursor = 'pointer';
expandButton.style.fontSize = '12px';
expandButton.style.zIndex = '9999';
expandButton.innerHTML = '展开信息';
expandButton.onclick = toggleIpInfo;
expandButton.style.display = 'block'; // 默认隐藏
document.body.appendChild(expandButton);
}
var contentElement = document.getElementById('ipInfoContent');
if (!contentElement) {
contentElement = document.createElement('div');
contentElement.id = 'ipInfoContent';
ipElement.appendChild(contentElement);
}
var textArea = document.getElementById('ipListInputTextArea');
if(!textArea)
{
contentElement = document.createElement('textarea');
contentElement.id = 'ipListInputTextArea';
ipElement.appendChild(contentElement);
}
if(!details) return;
const content = `
<div>
<strong>IPv4:</strong> ${details.query} <span id="copyButtonContainer1"></span>
</div>
<div>
<strong>IPv6:</strong> ${ipv6 ? ipv6 : 'N/A'} <span id="copyButtonContainer2"></span>
</div>
<div>
<strong>城市:</strong> ${details.city}, ${details.regionName}
</div>
<div>
<strong>zip:</strong> ${details.zip ? details.zip : 'N/A'}
</div>
<div>
<strong>国家:</strong> ${details.country}
</div>
<div>
<strong>ISP:</strong> ${details.isp}
</div>
<div>
<strong>AS:</strong> ${details.as}
</div>
<div>
<strong>风险评分:</strong> ${riskData ? riskData.score : 'N/A'}
</div>
<div>
<strong>风险类型:</strong> ${riskData ? riskData.risk : 'N/A'}
</div>
<div>
<strong>Ping0风险值:</strong> ${ping0Data ? ping0Data.riskValue : 'N/A'}
</div>
<div>
<strong>IP类型:</strong> ${ping0Data ? ping0Data.ipType : 'N/A'}
</div>
<div>
<strong>原生IP:</strong> ${ping0Data ? ping0Data.nativeIP : 'N/A'}
</div>
<hr>
`;
contentElement.innerHTML = content; // Use innerHTML instead of insertAdjacentHTML to replace old content
// 添加复制按钮到 copyButtonContainer
const copyButtonContainer1 = document.getElementById('copyButtonContainer1');
copyButtonContainer1.appendChild(createCopyButton(details.query));
const copyButtonContainer2 = document.getElementById('copyButtonContainer2');
copyButtonContainer2.appendChild(createCopyButton(ipv6));
if(ping0Data && ping0Data.ipType.includes('家') && ping0Data.riskValue && riskData && riskData.score)
{
let ping0Score = parseInt(ping0Data.riskValue.replace('%', ''));
let riskScore = parseInt(riskData.score);
if(ping0Score <= Ping0PassScore && riskScore < ScamalyticsPassScore) OutputLog.must(`IP: ${details.query} Score: ${ping0Score}/${riskScore} ${details.country} ${details.city}, ${details.regionName}`);
}
// if(riskData && riskData.score)
// {
// let riskScore = parseInt(riskData.score);
// if(riskScore < 10) OutputLog.must(`IP: ${details.query} RiskScore: ${riskScore} ${details.country} ${details.city}, ${details.regionName}`);
// }
}
function createCopyButton(text) {
const button = document.createElement('button');
button.innerHTML = '复制';
button.style.width = 'auto';
button.style.marginLeft = '5px';
button.style.cursor = 'pointer';
//button.style.backgroundColor = '#007bff';
//button.style.color = '#fff';
button.style.border = 'none';
button.style.padding = '2px 5px';
button.style.borderRadius = '3px';
button.onclick = (event) => {
event.stopPropagation(); // 阻止事件冒泡
navigator.clipboard.writeText(text).then(() => {
button.innerHTML = '已复制';
setTimeout(() => {
button.innerHTML = '复制';
}, 500);
}).catch(err => {
OutputLog.error('复制失败: ', err);
});
};
return button;
}
function toggleIpInfo() {
const ipElement = document.getElementById('ipInfo');
const expandButton = document.getElementById('expandIpInfo');
const toggleButton = document.getElementById('toggleIpInfo');
if (ipElement.style.right === '0px') {
ipElement.style.right = '-500px'; // 将其隐藏到右侧,调整宽度以适应内容
toggleButton.innerHTML = '展开信息';
toggleButton.style.display = 'none';
expandButton.style.display = 'block';
} else {
ipElement.style.right = '0px';
toggleButton.innerHTML = '隐藏信息';
toggleButton.style.display = 'inline-block';
expandButton.style.display = 'none';
}
}
let initialTop = 10;
let initialY = 0;
let dragging = false;
function startDragging(e) {
OutputLog.log('Start dragging...');
dragging = true;
initialY = e.clientY;
const ipElement = document.getElementById('ipInfo');
const expandButton = document.getElementById('expandIpInfo');
initialTop = parseInt(ipElement.style.top, 10);
expandButton.style.top = ipElement.style.top; // 同步expandButton的位置
document.addEventListener('mousemove', handleDragging);
document.addEventListener('mouseup', stopDragging);
}
function handleDragging(e) {
if (dragging) {
OutputLog.log('Dragging...');
const deltaY = e.clientY - initialY;
const newTop = initialTop + deltaY;
const ipElement = document.getElementById('ipInfo');
const expandButton = document.getElementById('expandIpInfo');
ipElement.style.top = newTop + 'px';
expandButton.style.top = newTop + 'px'; // 同步expandButton的位置
}
}
function stopDragging() {
OutputLog.log('Stop dragging...');
dragging = false;
document.removeEventListener('mousemove', handleDragging);
document.removeEventListener('mouseup', stopDragging);
const ipElement = document.getElementById('ipInfo');
GM_setValue('ipInfoTop', ipElement.style.top);
const expandButton = document.getElementById('expandIpInfo');
GM_setValue('expandButtonTop', expandButton.style.top); // 同步保存expandButton的位置
}
// 初始创建ipElement,但不触发数据获取
displayIPDetails(null,null, null, null);
//fetchCurrentIP();
})();
这个工具的作用就是,将文本框中所有的ip地址(暂时没处理ipv6)进行检测,将其中两个体检站(ping0和scamalytics)的得分都低于设定分数(默认是10分)的ip在控制台输出。
代码中有三个变量,使用时可以自行修改:
WaitingSec:每个ip之间的处理间隔,单位为秒,默认是10,如果网络不太好建议设高一些。
Ping0PassScore:ping0站的分数线,默认是10,如果觉得太严格可以调高。
ScamalyticsPassScore:scamalytics站的分数线,同上。
使用方法大概是这样的:
将ip地址逐行填入文本框后,点击刷新IP信息,就会自动开始检测所有ip。
此时打开页面的控制台(最好清空一下消息),然后就可以放在一边了。有符合条件的ip,就会自动输出到控制台上。全部ip检测完毕后,会有个alert提示。
这个只是分享给论坛里不懂程序的坛友们,因为代码实在是太简陋了,不太好意思见人,还请各位技术大佬直接忽略。