- 申请ID:ymyuuu
- 个人邮箱:ymyuuu@qq.com
- 原创技术文章:
逆向工程:凤鸟查询公司信息API的分析与实现
一、背景与动机:
通过API接口获取企业信息,既能提高效率,也能保障数据的实时性和准确性。基于此,我对凤鸟查询公司信息的API进行了逆向工程研究,编写了一段代码,能够自动化完成企业信息的获取和处理。
二、功能模块详解:
-
身份验证模块:
- 功能描述:获取授权令牌是与API交互的第一步。此模块通过模拟用户登录操作,向API请求授权令牌(Token),该令牌将在后续的数据查询中用作认证凭据。
-
代码实现:
async function getAuthorizationToken() {
try {
const response = await fetch("https://riskbird.com/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
captcha: "",
inviteCode: null,
mobile: "xx", //账号
password: "xx",//密码
smsCode: "",
type: "password"
}),
});
const data = await response.json();
if (data.code === 20000) {
return data.data.token;
} else {
throw new Error("查询失败");
}
} catch {
throw new Error("查询失败");
}
}
- 技术要点:在发送POST请求时,附带必要的登录信息(如手机号和密码),API会在验证通过后返回一个授权令牌,用于后续的查询请求。
-
查询数据模块:
- 功能描述:通过授权令牌和用户提供的查询关键词,从API获取目标企业的详细信息。
-
代码实现:
async function fetchQueryData(token, appUuid, searchKey) {
try {
const response = await fetch("https://riskbird.com/riskbird-api/newSearch", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Cookie": `app-uuid=${appUuid}; app-device=WEB; token=${token}`,
},
body: JSON.stringify({
pageNo: 1,
queryType: "1",
range: 10,
searchKey: searchKey,
selectConditionData: "{\"regionid\":\"\",\"status\":\"\",\"nicid\":\"\",\"sort_field\":\"\"}"
}),
});
const data = await response.json();
if (!data.success) {
throw new Error("查询失败");
}
return data.data.list.map((item) => {
const formattedItem = {
companyName: item.ENTNAME_SEARCH?.replace(/<\/?[^>]+(>|$)/g, ""),
historicalNames: item.ENTNAME_history || undefined,
status: item.ENTSTATUS || undefined,
legalRepresentative: item.faren || undefined,
unifiedSocialCreditCode: item.UNISCID || undefined,
registrationNumber: item.REGNO || undefined,
personId: item.personid || undefined,
phoneNumber: item.tels?.join(", ") || undefined,
email: item.emails?.join(", ") || undefined,
registeredCapital: item.regConcat || undefined,
establishmentDate: item.ESDATE || undefined,
address: item.DOM || undefined,
tags: item.tags || undefined,
riskTags: item.risk_tag_names || undefined,
website: item.WEBSITE || undefined
};
return Object.fromEntries(Object.entries(formattedItem).filter(([_, v]) => v !== undefined));
});
} catch {
throw new Error("查询失败");
}
}
- 技术要点:在这段代码中,授权令牌和UUID作为请求的必要凭据发送给API,返回的数据经过处理后,去除HTML标签及空字段,以简化和优化数据结构,便于前端展示。
-
数据处理模块:
- 功能描述:将API返回的复杂数据结构进行整理、清洗,提取出用户关心的核心信息,并以JSON格式返回前端。
- 代码实现:
function createSuccessResponse(data) {
return new Response(JSON.stringify({
status: "success",
message: "逆向公司数据成功",
coinfo: data
}), {
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
- 技术要点:通过提取API响应中的关键信息,如公司名称、法定代表人、注册资本等,确保数据的完整性和准确性。同时过滤掉空值字段,以减少不必要的信息冗余。
-
错误处理机制:
- 功能描述:在程序的各个关键环节加入了详细的错误处理逻辑,确保在任何异常情况下,程序都能给出明确的错误信息,避免程序崩溃。
- 代码实现:
function createErrorResponse(message, status) {
return new Response(JSON.stringify({
status: "error",
message: message
}), {
status: status,
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
- 技术要点:错误处理不仅确保了程序的稳定性,还能向用户明确反馈问题所在,便于后续的调试和修正。
三、UUID生成的实现:
四、部署方式:
-
登录 Cloudflare 账号:
-
创建一个新的 Worker:
- 登录后,点击左侧菜单中的“Workers”。
- 在“Workers”页面中,点击“Create a Service”按钮。
- 在弹出的窗口中,为你的服务起一个名称,比如“CompanyInfoAPI”,然后点击“Create Service”。
- 在接下来的页面中,选择“Start from scratch”模板,这会给你一个空白的 JavaScript 文件来编写你的代码。
-
粘贴代码:
- 删除编辑器中默认的代码。
-
将以下完整代码粘贴到编辑器中:
async function handleRequest(request) {
const url = new URL(request.url);
// 验证路径和方法
if (url.pathname !== "/api" || !["GET", "POST"].includes(request.method)) {
return createErrorResponse("不许调皮o", 400);
}
// 获取查询参数
const searchKey = request.method === "GET"
? url.searchParams.get("searchKey")
: (await request.json()).searchKey;
if (!searchKey) {
return createErrorResponse("不许调皮o", 400);
}
try {
const token = await getAuthorizationToken();
const appUuid = generateUUID(); // 生成随机 UUID
const queryData = await fetchQueryData(token, appUuid, searchKey);
return createSuccessResponse(queryData);
} catch {
return createErrorResponse("查询失败", 500);
}
}
async function getAuthorizationToken() {
try {
const response = await fetch("https://riskbird.com/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
captcha: "",
inviteCode: null,
mobile: "xx", //账号
password: "xx",//密码
smsCode: "",
type: "password"
}),
});
const data = await response.json();
if (data.code === 20000) {
return data.data.token;
} else {
throw new Error("查询失败");
}
} catch {
throw new Error("查询失败");
}
}
async function fetchQueryData(token, appUuid, searchKey) {
try {
const response = await fetch("https://riskbird.com/riskbird-api/newSearch", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Cookie": `app-uuid=${appUuid}; app-device=WEB; token=${token}`,
},
body: JSON.stringify({
pageNo: 1,
queryType: "1",
range: 10,
searchKey: searchKey,
selectConditionData: "{\"regionid\":\"\",\"status\":\"\",\"nicid\":\"\",\"sort_field\":\"\"}"
}),
});
const data = await response.json();
if (!data.success) {
throw new Error("查询失败");
}
// 提取和简化所需字段并过滤空字段
return data.data.list.map((item) => {
const formattedItem = {
companyName: item.ENTNAME_SEARCH?.replace(/<\/?[^>]+(>|$)/g, ""),
historicalNames: item.ENTNAME_history || undefined,
status: item.ENTSTATUS || undefined,
legalRepresentative: item.faren || undefined, // 添加 `faren` 字段
unifiedSocialCreditCode: item.UNISCID || undefined,
registrationNumber: item.REGNO || undefined,
personId: item.personid || undefined,
phoneNumber: item.tels?.join(", ") || undefined,
email: item.emails?.join(", ") || undefined,
registeredCapital: item.regConcat || undefined,
establishmentDate: item.ESDATE || undefined,
address: item.DOM || undefined,
tags: item.tags || undefined,
riskTags: item.risk_tag_names || undefined,
website: item.WEBSITE || undefined
};
// 过滤掉值为 undefined 的字段
return Object.fromEntries(Object.entries(formattedItem).filter(([_, v]) => v !== undefined));
});
} catch {
throw new Error("查询失败");
}
}
// 生成随机 UUID
function generateUUID() {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
}
function createSuccessResponse(data) {
return new Response(JSON.stringify({
status: "success",
message: "逆向公司数据成功",
coinfo: data
}), {
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
function createErrorResponse(message, status) {
return new Response(JSON.stringify({
status: "error",
message: message
}), {
status: status,
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
-
保存并部署:
- 确认代码已经正确粘贴到编辑器中,点击页面右上角的“Save and Deploy”按钮。
- 部署完成后,Cloudflare 将为你的 Worker 生成一个唯一的 URL,你可以通过这个 URL 来访问你的 API。
-
测试 API:
四、总结
- 通过本次逆向工程,我成功实现了对凤鸟公司信息查询API的完整调用,掌握了API请求、身份认证、数据处理等关键技术点。
- 此代码可以应用于多个场景,如企业信息自动化采集、商业调查分析等,为用户提供了便捷而高效的数据查询工具。
- 本人郑重声明,以上代码及技术文章内容为本人原创,未有抄袭或冒用他人作品的行为。如有任何疑问或需进一步验证,本人愿意提供相关的开发记录和证明材料。请论坛管理团队予以审核,谢谢!
|