申请会员ID:ymyuuu
1. **申请ID**:ymyuuu2. **个人邮箱**:ymyuuu@qq.com
3. **原创技术文章**:
#### **逆向工程:凤鸟查询公司信息API的分析与实现**
**一、背景与动机:**
通过API接口获取企业信息,既能提高效率,也能保障数据的实时性和准确性。基于此,我对凤鸟查询公司信息的API进行了逆向工程研究,编写了一段代码,能够自动化完成企业信息的获取和处理。
**二、功能模块详解:**
1. **身份验证模块**:
- **功能描述**:获取授权令牌是与API交互的第一步。此模块通过模拟用户登录操作,向API请求授权令牌(Token),该令牌将在后续的数据查询中用作认证凭据。
- **代码实现**:
```javascript
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会在验证通过后返回一个授权令牌,用于后续的查询请求。
2. **查询数据模块**:
- **功能描述**:通过授权令牌和用户提供的查询关键词,从API获取目标企业的详细信息。
- **代码实现**:
```javascript
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 !== undefined));
});
} catch {
throw new Error("查询失败");
}
}
```
- **技术要点**:在这段代码中,授权令牌和UUID作为请求的必要凭据发送给API,返回的数据经过处理后,去除HTML标签及空字段,以简化和优化数据结构,便于前端展示。
3. **数据处理模块**:
- **功能描述**:将API返回的复杂数据结构进行整理、清洗,提取出用户关心的核心信息,并以JSON格式返回前端。
- **代码实现**:
```javascript
function createSuccessResponse(data) {
return new Response(JSON.stringify({
status: "success",
message: "逆向公司数据成功",
coinfo: data
}), {
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
```
- **技术要点**:通过提取API响应中的关键信息,如公司名称、法定代表人、注册资本等,确保数据的完整性和准确性。同时过滤掉空值字段,以减少不必要的信息冗余。
4. **错误处理机制**:
- **功能描述**:在程序的各个关键环节加入了详细的错误处理逻辑,确保在任何异常情况下,程序都能给出明确的错误信息,避免程序崩溃。
- **代码实现**:
```javascript
function createErrorResponse(message, status) {
return new Response(JSON.stringify({
status: "error",
message: message
}), {
status: status,
headers: { "Content-Type": "application/json; charset=utf-8" },
});
}
```
- **技术要点**:错误处理不仅确保了程序的稳定性,还能向用户明确反馈问题所在,便于后续的调试和修正。
**三、UUID生成的实现:**
- **功能描述**:为确保每个请求的唯一性,我实现了一个UUID生成器,用于为每次查询生成一个随机的UUID。
- **代码实现**:
```javascript
function generateUUID() {
return ( + -1e3 + -4e3 + -8e3 + -1e11).replace(//g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1)) & 15 >> c / 4).toString(16)
);
}
```
- **技术要点**:UUID生成采用了JavaScript的`crypto.getRandomValues`方法,确保每次生成的UUID都具有高度的随机性,防止重复请求导致的冲突。
**四、部署方式:**
1. **登录 Cloudflare 账号**:
- 访问 (https://www.cloudflare.com/) 并登录到你的账号。如果还没有账号,请先注册一个免费的 Cloudflare 账户。
2. **创建一个新的 Worker**:
- 登录后,点击左侧菜单中的“Workers”。
- 在“Workers”页面中,点击“Create a Service”按钮。
- 在弹出的窗口中,为你的服务起一个名称,比如“CompanyInfoAPI”,然后点击“Create Service”。
- 在接下来的页面中,选择“Start from scratch”模板,这会给你一个空白的 JavaScript 文件来编写你的代码。
3. **粘贴代码**:
- 删除编辑器中默认的代码。
- 将以下完整代码粘贴到编辑器中:
```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 !== undefined));
});
} catch {
throw new Error("查询失败");
}
}
// 生成随机 UUID
function generateUUID() {
return ( + -1e3 + -4e3 + -8e3 + -1e11).replace(//g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1)) & 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));
});
```
4. **保存并部署**:
- 确认代码已经正确粘贴到编辑器中,点击页面右上角的“Save and Deploy”按钮。
- 部署完成后,Cloudflare 将为你的 Worker 生成一个唯一的 URL,你可以通过这个 URL 来访问你的 API。
5. **测试 API**:
- 部署完成后,你可以通过访问生成的 URL 来测试 API。你可以在浏览器中直接访问,例如你可以访问我的示例:
```
https://aged-cherry-0f81.ymyuuu.workers.dev/api?searchKey=公司名称
```
- 也可以使用 Postman 等工具,发送 GET 或 POST 请求来查询公司信息。
- **请注意,复制代码之前请讲账号密码替换成自己在凤鸟官网注册的账号密码。**
**四、总结**
- 通过本次逆向工程,我成功实现了对凤鸟公司信息查询API的完整调用,掌握了API请求、身份认证、数据处理等关键技术点。
- 此代码可以应用于多个场景,如企业信息自动化采集、商业调查分析等,为用户提供了便捷而高效的数据查询工具。
- **本人郑重声明,以上代码及技术文章内容为本人原创,未有抄袭或冒用他人作品的行为。如有任何疑问或需进一步验证,本人愿意提供相关的开发记录和证明材料。请论坛管理团队予以审核,谢谢!** 你这是AI帮你写的吧? Hmily 发表于 2024-8-27 17:51
你这是AI帮你写的吧?
他就帮我改了一下md格式,看着稍微顺眼一点,代码绝对是我自己写的 游客 183.199.24.x 发表于 2024-8-27 19:30
他就帮我改了一下md格式,看着稍微顺眼一点,代码绝对是我自己写的
抱歉,未能达到申请要求,申请不通过,可以关注论坛官方微信(吾爱破解论坛),等待开放注册通知。
页:
[1]