---
title: "04-kingdee_data_proc_api"
created: 2026-04-02
tags:
- 项目
aliases:
- kingdee_data_proc_api
---
# kingdee_data_proc_api.py
### `kingdee_data_proc_api.py` — 金蝶 JS 文件解析
职位数据直接发布在静态 `jobs.js` 里(较少见的方案):正则从 JS 文本提取 `jobs = [...]` 数组解析成 JSON,再拼伪 HTML 落盘。
## 代码
```python
import time
import hashlib
import os
import requests
from urllib.parse import urlencode
import sys
sys.path.append('../')
import json
from utils import ner_logger
import re
from playwright.sync_api import sync_playwright
import threading
from concurrent.futures import ThreadPoolExecutor
# 请求头:伪装浏览器访问金蝶招聘页面
headers = {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Referer": "https://campus.51job.com/kingdee/",
"Sec-Ch-Ua": '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": '"Windows"',
"Sec-Fetch-Dest": "script",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-origin",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36"
}
# 获取金蝶招聘职位数据(从JS文件中提取职位数组)
def get_kingdee_job_data(url):
try:
with requests.Session() as s:
resp = s.get(url, headers=headers, timeout=15)
if resp.status_code == 200:
js_content = resp.text
# 正则提取 jobs = [...] 格式的职位数据
jobs_match = re.search(r'(?:var\s+)?jobs\s*=\s*(\[.*?\]);?', js_content, re.DOTALL)
if jobs_match:
jobs_str = jobs_match.group(1)
jobs_data = json.loads(jobs_str)
return True, jobs_data
else:
# 兜底:提取任意数组
array_match = re.search(r'(\[.*\])', js_content, re.DOTALL)
if array_match:
array_str = array_match.group(1)
array_data = json.loads(array_str)
return True, array_data
else:
ner_logger.info("未能从JS文件中提取职位数据")
return False, []
else:
ner_logger.info("请求失败,状态码: %s", resp.status_code)
return False, []
except Exception as e:
ner_logger.info("请求金蝶招聘数据时出错: %s", str(e))
return False, []
# 将金蝶原始数据转为统一标准JSON
def transform_job_json(item, job_type, channel, tmp_file, json_file):
try:
# 字段映射
field_mapping = {
"announcement_name": "jobname", # 职位名称
"publish_time": "", # 发布时间(无)
"hd_dept": "organization", # 部门
"hd_loc": "city1", # 工作地点
"hd_job_num": "", # 招聘人数(无)
"hd_job_category": "type1" # 职位类别
}
# 构造详情页链接
detail_url = item.get("link", "")
if not detail_url:
job_id = item.get("jobid", "")
if job_id:
detail_url = f"https://campus.51job.com/kingdee/job.html?jobid={job_id}"
else:
detail_url = "https://campus.51job.com/kingdee/"
# 固定公共字段
fixed_fields = {
"link": detail_url,
"full_url": detail_url,
"last_url": detail_url,
"file_path": tmp_file,
"parent_url": "https://campus.51job.com/kingdee/",
"channel": channel,
"job_type": job_type
}
target_json = {}
# 映射字段
for target_field, source_field in field_mapping.items():
if source_field:
target_json[target_field] = item.get(source_field, "")
else:
target_json[target_field] = ""
target_json.update(fixed_fields)
# 保存JSON
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(target_json, f, ensure_ascii=False, indent=4)
return True
except Exception as e:
ner_logger.error("转换职位数据时出错: %s", str(e))
return False
# 生成金蝶职位详情HTML页面
def generate_kingdee_job_html(item, tmp_file):
try:
# 提取字段
job_name = item.get("jobname", "")
organization = item.get("organization", "")
city = item.get("city1", "")
job_type = item.get("type1", "")
job_id = item.get("jobid", "")
address = item.get("address", "")
job_description = item.get("info", "").replace("\r\n", "
").replace("\n", "
")
job_link = item.get("link", "")
mobile_link = item.get("linkM", "")
# 拼接HTML
html_content = f'''