Files
SearchCompany/demo/qichacha_aiqicha.js
manchuwork 6444fecd4e aiqicha
2025-09-25 14:47:19 +08:00

832 lines
27 KiB
JavaScript

// ==UserScript==
// @name 爱企查&企查查等
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 在页面右下角添加工具按钮,支持复制源码和解析公司信息
// @author You
// @match https://www.qcc.com/firm/*
// @match https://aiqicha.baidu.com/company_detail_*
// @grant none
// ==/UserScript==
(function () {
"use strict";
// 工具类 - 存放通用函数
class ToolUtils {
static cleanText(text) {
return text
.replace(/\s+/g, " ")
.replace(/[\r\n\t]/g, "")
.trim();
}
static extractText(doc, selectors) {
for (const selector of selectors) {
const element = doc.querySelector(selector);
if (element && element.textContent.trim()) {
return element.textContent.trim();
}
}
return "";
}
static copyToClipboard(content, successMessage) {
const textarea = document.createElement("textarea");
textarea.value = content;
textarea.style.position = "fixed";
textarea.style.top = "0";
textarea.style.left = "0";
textarea.style.width = "1px";
textarea.style.height = "1px";
textarea.style.opacity = "0";
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
if (successMessage) {
this.showAutoCloseMessage(successMessage, "success");
}
}
static showAutoCloseMessage(message, type = "info") {
// 创建一个自动关闭的提示框替代 alert
const alertBox = document.createElement("div");
alertBox.textContent = message;
alertBox.style.position = "fixed";
alertBox.style.top = "50%";
alertBox.style.left = "50%";
alertBox.style.transform = "translate(-50%, -50%)";
// 根据消息类型设置不同颜色
if (type === "success") {
alertBox.style.backgroundColor = "#52c41a";
} else if (type === "error") {
alertBox.style.backgroundColor = "#f5222d";
} else {
alertBox.style.backgroundColor = "#1890ff";
}
alertBox.style.color = "white";
alertBox.style.padding = "10px 20px";
alertBox.style.borderRadius = "4px";
alertBox.style.zIndex = "10001";
alertBox.style.boxShadow = "0 2px 8px rgba(0,0,0,0.15)";
alertBox.style.transition = "opacity 0.3s";
document.body.appendChild(alertBox);
// 2秒后自动关闭
setTimeout(() => {
if (document.body.contains(alertBox)) {
// 添加淡出效果
alertBox.style.opacity = "0";
// 真正移除元素
setTimeout(() => {
if (document.body.contains(alertBox)) {
document.body.removeChild(alertBox);
}
}, 300);
}
}, 2000);
}
static showResult(data) {
const modal = document.createElement("div");
modal.style.position = "fixed";
modal.style.top = "50%";
modal.style.left = "50%";
modal.style.transform = "translate(-50%, -50%)";
modal.style.width = "600px";
modal.style.maxHeight = "80vh";
modal.style.overflowY = "auto";
modal.style.backgroundColor = "white";
modal.style.padding = "20px";
modal.style.boxShadow = "0 0 10px rgba(0,0,0,0.3)";
modal.style.zIndex = "10000";
const pre = document.createElement("pre");
pre.textContent = JSON.stringify(data, null, 2);
pre.style.whiteSpace = "pre-wrap";
pre.style.wordWrap = "break-word";
const copyBtn = document.createElement("button");
copyBtn.textContent = "复制JSON";
copyBtn.style.marginTop = "10px";
copyBtn.style.padding = "8px 16px";
copyBtn.style.backgroundColor = "#52c41a";
copyBtn.style.color = "white";
copyBtn.style.border = "none";
copyBtn.style.borderRadius = "4px";
copyBtn.style.cursor = "pointer";
copyBtn.addEventListener("click", () => {
navigator.clipboard
.writeText(JSON.stringify(data, null, 2))
.then(() => this.showAutoCloseMessage("已复制到剪贴板", "success"))
.catch((err) => alert("复制失败: " + err));
});
const closeBtn = document.createElement("button");
closeBtn.textContent = "关闭";
closeBtn.style.marginLeft = "10px";
closeBtn.style.marginTop = "10px";
closeBtn.style.padding = "8px 16px";
closeBtn.style.backgroundColor = "#f5222d";
closeBtn.style.color = "white";
closeBtn.style.border = "none";
closeBtn.style.borderRadius = "4px";
closeBtn.style.cursor = "pointer";
closeBtn.addEventListener("click", () => {
document.body.removeChild(modal);
});
modal.innerHTML = '<h2 style="margin-top: 0;">企业信息解析结果</h2>';
modal.appendChild(pre);
modal.appendChild(document.createElement("br"));
modal.appendChild(copyBtn);
modal.appendChild(closeBtn);
document.body.appendChild(modal);
// // Automatically close the modal after 2 seconds
// setTimeout(() => {
// if (document.body.contains(modal)) {
// document.body.removeChild(modal);
// }
// }, 2000);
}
}
// 爱企查解析类
class AiQiChaParser {
getPhoneNumber() {
// 查找电话信息容器
const phoneContainer = document.querySelector(
"div.business-info div.telphone-lists-wrap"
);
if (!phoneContainer) return "未找到电话信息";
// 查找包含电话号码的元素
const phoneElement = phoneContainer.querySelector("span.copy-box span");
if (!phoneElement) return "未找到电话号码";
return ToolUtils.cleanText(phoneElement.textContent);
}
constructor() {
this.table = null;
}
// 初始化表格
initTable() {
this.table = document.querySelector("table.zx-detail-basic-table");
if (!this.table) {
alert("未找到企业信息表格");
return false;
}
return true;
}
// 获取优化后的值
getOptimizedValue(title) {
const cells = Array.from(this.table.querySelectorAll("td"));
const titleCell = cells.find(
(cell) => ToolUtils.cleanText(cell.textContent) === title
);
if (!titleCell) return null;
let valueCell = titleCell.nextElementSibling;
if (!valueCell) return null;
const valueElement =
valueCell.querySelector(".enter-bg-ele") ||
valueCell.querySelector(".addr-enter-bg-ele") ||
valueCell;
return ToolUtils.cleanText(valueElement.textContent);
}
// 获取法定代表人
getLegalRepresentative() {
const legalElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) => ToolUtils.cleanText(td.textContent) === "法定代表人");
if (legalElements.length > 0) {
const valueCell = legalElements[0].nextElementSibling;
if (valueCell && valueCell.classList.contains("image-text-content")) {
const nameElement = valueCell.querySelector(".person-name-warp a");
if (nameElement) {
return ToolUtils.cleanText(nameElement.textContent);
}
return ToolUtils.cleanText(valueCell.textContent);
}
}
const titleElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) => td.textContent.includes("法定代表人"));
if (titleElements.length > 0 && titleElements[0].nextElementSibling) {
const valueCell = titleElements[0].nextElementSibling;
return ToolUtils.cleanText(valueCell.textContent);
}
return null;
}
// 获取统一社会信用代码
getUnifiedSocialCreditCode() {
const codeElements = Array.from(this.table.querySelectorAll("td")).filter(
(td) => {
return (
td.textContent.includes("统一社会信用代码") &&
td.nextElementSibling &&
td.nextElementSibling.classList.contains("table-regCapital-lable")
);
}
);
if (codeElements.length > 0) {
const valueCell = codeElements[0].nextElementSibling;
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
const taxElements = Array.from(this.table.querySelectorAll("td")).filter(
(td) => td.textContent.includes("纳税人识别号")
);
if (taxElements.length > 0 && taxElements[0].nextElementSibling) {
const valueCell = taxElements[0].nextElementSibling;
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
return null;
}
// 获取工商注册号
getBusinessRegistrationNo() {
const regElements = Array.from(this.table.querySelectorAll("td")).filter(
(td) => ToolUtils.cleanText(td.textContent).includes("工商注册号")
);
if (regElements.length > 0 && regElements[0].nextElementSibling) {
const valueCell = regElements[0].nextElementSibling;
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
return null;
}
// 获取组织机构代码
getOrganizationCode() {
const orgCodeElements = Array.from(
this.table.querySelectorAll(".poptip-wrap-org-no")
).filter((el) => el.textContent.includes("组织机构代码"));
if (orgCodeElements.length > 0) {
const valueCell = orgCodeElements[0].closest("td").nextElementSibling;
if (valueCell && valueCell.classList.contains("enter-bg")) {
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
}
const titleElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) => ToolUtils.cleanText(td.textContent) === "组织机构代码");
if (titleElements.length > 0 && titleElements[0].nextElementSibling) {
const valueCell = titleElements[0].nextElementSibling;
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
return null;
}
// 获取纳税人识别号
getTaxpayerId() {
const taxElements = Array.from(this.table.querySelectorAll("td")).filter(
(td) => ToolUtils.cleanText(td.textContent).includes("纳税人识别号")
);
if (taxElements.length > 0 && taxElements[0].nextElementSibling) {
const valueCell = taxElements[0].nextElementSibling;
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
const creditElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) =>
ToolUtils.cleanText(td.textContent).includes("统一社会信用代码")
);
if (creditElements.length > 0 && creditElements[0].nextElementSibling) {
const valueCell = creditElements[0].nextElementSibling;
const rawValue =
valueCell.querySelector(".enter-bg-ele")?.textContent ||
valueCell.textContent;
return ToolUtils.cleanText(rawValue);
}
return null;
}
// 获取参保人数
getInsuranceNumber() {
const insuranceElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) => {
return (
td.textContent.includes("参保人数") &&
td.querySelector(".insurance-info")
);
});
if (insuranceElements.length > 0) {
const valueCell = insuranceElements[0].nextElementSibling;
if (!valueCell) return null;
const rawText = valueCell.textContent.replace(/[\r\n\t]/g, "").trim();
const match = rawText.match(/(\d+人)/);
return match ? match[0] : null;
}
const registrationElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) => td.textContent.includes("登记机关"));
if (
registrationElements.length > 0 &&
registrationElements[0].previousElementSibling
) {
const valueCell = registrationElements[0].previousElementSibling;
const rawText = valueCell.textContent.replace(/[\r\n\t]/g, "").trim();
const match = rawText.match(/(\d+人)/);
return match ? match[0] : null;
}
return null;
}
// 获取核准日期
getApprovalDate() {
const approvalElements = Array.from(
this.table.querySelectorAll(".poptip-wrap-annual-date")
).filter((el) => el.textContent.includes("核准日期"));
if (approvalElements.length > 0) {
const valueCell = approvalElements[0].closest("td").nextElementSibling;
if (valueCell) {
const rawValue = valueCell.textContent
.replace(/[\r\n\t]/g, "")
.trim();
if (/^\d{4}-\d{2}-\d{2}$/.test(rawValue)) {
return rawValue;
}
}
}
const titleElements = Array.from(
this.table.querySelectorAll("td")
).filter((td) => ToolUtils.cleanText(td.textContent) === "核准日期");
if (titleElements.length > 0 && titleElements[0].nextElementSibling) {
const valueCell = titleElements[0].nextElementSibling;
const rawValue = ToolUtils.cleanText(valueCell.textContent);
if (/^\d{4}-\d{2}-\d{2}$/.test(rawValue)) {
return rawValue;
}
}
return null;
}
// 解析公司信息主方法
parseCompanyInfo() {
if (!this.initTable()) return;
const companyData = {
企业名称: this.getOptimizedValue("企业名称"),
统一社会信用代码: this.getUnifiedSocialCreditCode(),
法定代表人: this.getLegalRepresentative(),
电话: this.getPhoneNumber(),
经营状态: this.getOptimizedValue("经营状态"),
成立日期: this.getOptimizedValue("成立日期"),
行政区划: this.getOptimizedValue("行政区划"),
注册资本: this.getOptimizedValue("注册资本"),
实缴资本: this.getOptimizedValue("实缴资本"),
企业类型: this.getOptimizedValue("企业类型"),
所属行业: this.getOptimizedValue("所属行业"),
工商注册号: this.getBusinessRegistrationNo(),
组织机构代码: this.getOrganizationCode(),
纳税人识别号: this.getTaxpayerId(),
纳税人资质: this.getOptimizedValue("纳税人资质"),
营业期限: this.getOptimizedValue("营业期限"),
核准日期: this.getApprovalDate(),
参保人数: this.getInsuranceNumber(),
登记机关: this.getOptimizedValue("登记机关"),
曾用名: this.getOptimizedValue("曾用名"),
注册地址: this.getOptimizedValue("注册地址"),
经营范围: this.getOptimizedValue("经营范围"),
};
ToolUtils.showResult(companyData);
}
}
// QCC解析类 企查查
class QCCParser {
constructor() {
this.table = null;
}
// 初始化表格
initTable() {
const cominfoNormal = document.querySelector("div.cominfo-normal");
if (!cominfoNormal) {
alert("未找到企业信息容器");
return false;
}
this.table = cominfoNormal.querySelector("table.ntable");
if (!this.table) {
alert("未找到企业信息表格");
return false;
}
return true;
}
// 获取优化后的值
getOptimizedValue(title) {
const headerCells = Array.from(this.table.querySelectorAll("td.tb"));
let value = null;
headerCells.forEach((header) => {
if (ToolUtils.cleanText(header.textContent).includes(title)) {
const valueCell = header.nextElementSibling;
if (valueCell) {
// 尝试从copy-value类中获取值
const copyValue = valueCell.querySelector(".copy-value");
if (copyValue) {
value = ToolUtils.cleanText(copyValue.textContent);
} else {
value = ToolUtils.cleanText(valueCell.textContent);
}
}
}
});
return value;
}
// 获取法定代表人
getLegalRepresentative() {
// Try the existing method first
const basicValue =
this.getOptimizedValue("法定代表人") || this.getOptimizedValue("法人");
if (basicValue && basicValue.trim()) {
// Remove any "关联企业 X" text
return basicValue.replace(/\s*关联企业\s*\d+$/, "").trim();
}
// If basic extraction fails, try more specific approach
const headerCell = Array.from(this.table.querySelectorAll("td.tb")).find(
(cell) => ToolUtils.cleanText(cell.textContent).includes("法定代表人")
);
if (!headerCell) return null;
const valueCell = headerCell.nextElementSibling;
if (!valueCell) return null;
// Try to find the name within the complex structure
// Look for anchor tags with target="_blank" which typically contain the legal representative's name
const nameLinks = valueCell.querySelectorAll('a[target="_blank"]');
for (const link of nameLinks) {
const name = ToolUtils.cleanText(link.textContent);
// Make sure it's not empty and doesn't contain obvious non-name text
if (name && !name.includes("关联企业") && !name.includes("复制")) {
return name;
}
}
// Alternative approach - look for the first anchor tag in the cell
const firstLink = valueCell.querySelector("a");
if (firstLink) {
const name = ToolUtils.cleanText(firstLink.textContent);
// Remove any trailing "关联企业 X" text
return name.replace(/\s*关联企业\s*\d+$/, "").trim();
}
// Fallback to general value extraction
const copyValue = valueCell.querySelector(".copy-value");
if (copyValue) {
const name = ToolUtils.cleanText(copyValue.textContent);
// Remove any trailing "关联企业 X" text
return name.replace(/\s*关联企业\s*\d+$/, "").trim();
}
const rawText = ToolUtils.cleanText(valueCell.textContent);
// Remove any trailing "关联企业 X" text
return rawText.replace(/\s*关联企业\s*\d+$/, "").trim();
}
// 获取统一社会信用代码
getUnifiedSocialCreditCode() {
return (
this.getOptimizedValue("统一社会信用代码") ||
this.getOptimizedValue("信用代码")
);
}
// 获取工商注册号
getBusinessRegistrationNo() {
return (
this.getOptimizedValue("工商注册号") || this.getOptimizedValue("注册号")
);
}
// 获取组织机构代码
getOrganizationCode() {
return this.getOptimizedValue("组织机构代码");
}
// 获取纳税人识别号
getTaxpayerId() {
return (
this.getOptimizedValue("纳税人识别号") ||
this.getUnifiedSocialCreditCode()
);
}
// 获取参保人数
getInsuranceNumber() {
// 查找参保人数表头
const headerCell = Array.from(this.table.querySelectorAll("td.tb")).find(
(cell) => ToolUtils.cleanText(cell.textContent).includes("参保人数")
);
if (!headerCell) return null;
const valueCell = headerCell.nextElementSibling;
if (!valueCell) return null;
// 提取参保人数数字
const numberSpan = valueCell.querySelector("span");
const number = numberSpan
? ToolUtils.cleanText(numberSpan.textContent)
: null;
// 提取年报年份
const reportLink = valueCell.querySelector("a.m-l-r-10");
const reportYear = reportLink
? ToolUtils.cleanText(reportLink.textContent)
: "";
// 组合结果
return number ? `${number}${reportYear}` : null;
}
// 获取联系电话
getPhoneNumber() {
// 查找联系信息容器
const contactInfo = document.querySelector("div.contact-info");
if (!contactInfo) return null;
// 查找右侧信息区域
const rightPart = contactInfo.querySelector("div.main-part-item.right");
if (!rightPart) return null;
// 查找包含电话的行
const rows = Array.from(rightPart.querySelectorAll("div.rline"));
const phoneRow = rows.find((row) =>
ToolUtils.cleanText(row.textContent).includes("电话:")
);
if (!phoneRow) return null;
// 提取电话号码
const spans = Array.from(
phoneRow.querySelectorAll("span.need-copy-field")
);
const phoneSpan = spans.find(
(span) => !ToolUtils.cleanText(span.textContent).includes("电话:")
);
return phoneSpan ? ToolUtils.cleanText(phoneSpan.textContent) : null;
}
// 获取核准日期
getApprovalDate() {
return (
this.getOptimizedValue("核准日期") || this.getOptimizedValue("成立日期")
);
}
// 解析公司信息主方法
parseCompanyInfo() {
if (!this.initTable()) return;
const companyData = {
企业名称:
this.getOptimizedValue("企业名称") ||
this.getOptimizedValue("公司名称"),
统一社会信用代码: this.getUnifiedSocialCreditCode(),
法定代表人: this.getLegalRepresentative(),
经营状态: this.getOptimizedValue("登记状态"),
成立日期: this.getOptimizedValue("成立日期"),
行政区划: this.getOptimizedValue("行政区划"),
注册资本: this.getOptimizedValue("注册资本"),
实缴资本: this.getOptimizedValue("实缴资本"),
企业类型: this.getOptimizedValue("企业类型"),
所属行业: this.getOptimizedValue("国标行业"),
工商注册号: this.getBusinessRegistrationNo(),
组织机构代码: this.getOrganizationCode(),
纳税人识别号: this.getTaxpayerId(),
纳税人资质: this.getOptimizedValue("纳税人资质"),
营业期限: this.getOptimizedValue("营业期限"),
核准日期: this.getApprovalDate(),
参保人数: this.getInsuranceNumber(),
电话: this.getPhoneNumber(),
登记机关: this.getOptimizedValue("登记机关"),
曾用名: this.getOptimizedValue("曾用名"),
注册地址: this.getOptimizedValue("注册地址"),
经营范围: this.getOptimizedValue("经营范围"),
};
ToolUtils.showResult(companyData);
}
}
// 创建按钮容器
function createButtonContainer() {
const container = document.createElement("div");
container.id = "tool-container";
Object.assign(container.style, {
position: "fixed",
right: "20px",
bottom: "20px",
zIndex: "9999",
display: "flex",
flexDirection: "column",
gap: "10px",
width: "40px",
height: "40px",
backgroundColor: "#4CAF50",
borderRadius: "50%",
transition: "all 0.3s ease",
overflow: "hidden",
cursor: "move",
});
// +号指示器
const plusSign = document.createElement("div");
plusSign.textContent = "+";
Object.assign(plusSign.style, {
color: "white",
fontSize: "24px",
textAlign: "center",
lineHeight: "40px",
width: "100%",
});
container.appendChild(plusSign);
// 悬停展开效果
container.addEventListener("mouseenter", () => {
container.style.width = "150px";
container.style.height = "auto";
container.style.borderRadius = "8px";
});
container.addEventListener("mouseleave", () => {
container.style.width = "40px";
container.style.height = "40px";
container.style.borderRadius = "50%";
});
// 添加拖动功能
let isDragging = false;
let offsetX, offsetY;
// 鼠标按下开始拖动
container.addEventListener("mousedown", (e) => {
// 只有点击+号区域才允许拖动
if (e.target === plusSign || e.target === container) {
isDragging = true;
const rect = container.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
container.style.cursor = "grabbing";
// 阻止事件冒泡和默认行为
e.stopPropagation();
e.preventDefault();
}
});
// 鼠标移动时更新位置
document.addEventListener("mousemove", (e) => {
if (!isDragging) return;
container.style.left = e.clientX - offsetX + "px";
container.style.top = e.clientY - offsetY + "px";
container.style.right = "auto";
container.style.bottom = "auto";
});
// 鼠标释放结束拖动
document.addEventListener("mouseup", () => {
if (isDragging) {
isDragging = false;
container.style.cursor = "move";
}
});
// 创建功能按钮
function createButton(text, onClick) {
const button = document.createElement("button");
button.textContent = text;
Object.assign(button.style, {
padding: "8px 12px",
border: "none",
borderRadius: "4px",
backgroundColor: "white",
color: "#333",
cursor: "pointer",
width: "100%",
transition: "backgroundColor 0.2s",
});
button.addEventListener(
"mouseenter",
() => (button.style.backgroundColor = "#f0f0f0")
);
button.addEventListener(
"mouseleave",
() => (button.style.backgroundColor = "white")
);
button.addEventListener("click", onClick);
return button;
}
// 复制源码按钮
const copySourceButton = createButton("复制源码", () => {
const html = document.documentElement.outerHTML;
copyToClipboard(html, "HTML源码已复制到剪贴板");
/*
navigator.clipboard
.writeText(html)
.then(() => {
alert("源码已复制到剪贴板");
})
.catch((err) => {
console.error("复制失败:", err);
});
*/
});
// 解析公司信息按钮
const parseInfoButton = createButton("解析公司信息", () => {
// 根据当前URL选择对应的解析器
let parser;
if (window.location.host.includes("aiqicha.baidu.com")) {
parser = new AiQiChaParser();
} else if (window.location.host.includes("qcc.com")) {
parser = new QCCParser();
} else {
alert("不支持的网站");
return;
}
parser.parseCompanyInfo();
});
// 添加按钮到容器
container.appendChild(copySourceButton);
container.appendChild(parseInfoButton);
document.body.appendChild(container);
}
// 页面加载完成后创建按钮
window.addEventListener("load", createButtonContainer);
})();