JobData/app/services/crawler/_boss_client.py
win 2b94f15b56 fix(04): correct architecture — private files use crawler_core directly
Architecture clarification from user: spiderJobs/ is standalone execution,
NOT meant to be imported by app/. Correct dependency graph:

  crawler_core   ← shared base library
    ↑        ↑
spiderJobs  app/services/crawler/
(standalone) (FastAPI backend, private layer)

Changes:
- boss.py/qcwy.py/zhilian.py: revert import back to private _boss_api etc.
- _boss/job51/zhilian_api.py: use crawler_core.base.Result/BaseFetcher/BaseSearcher
  + fix self._http → self.http_client
- _boss/job51/zhilian_client.py: use crawler_core.http_client.HTTPClient
  + _boss_client uses crawler_core.boss.sign.BossSign directly
- _boss/job51/zhilian_sign.py: backward-compat stubs → crawler_core.*.sign

Full regression: 106 passed in 0.68s
2026-03-21 19:39:30 +08:00

100 lines
3.2 KiB
Python

# ⚠️ DEPRECATED — 2026-03-21
# 此文件是内部手工复制文件,已废弃,不再由任何 facade 引用。
# 请改用 spiderJobs.platforms.* 或 crawler_core 中的对应模块。
# 将在下一里程碑中删除。
#
"""
Boss直聘 HTTP 客户端
复制自 spiderJobs/platforms/boss/client.py — import 改为本地引用
"""
from __future__ import annotations
from typing import Any, Optional
from crawler_core.http_client import HTTPClient
from crawler_core.boss.sign import BossSign
BASE_URL = "https://www.zhipin.com"
BOSS_HEADERS = {
"content-type": "application/x-www-form-urlencoded",
"user-agent": (
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 "
"(KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 "
"MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI "
"MiniProgramEnv/Mac MacWechat/WMPF MacWechat/3.8.7(0x13080712) "
"UnifiedPCMacWechat(0xf2641702) XWEB/18788"
),
"x-requested-with": "XMLHttpRequest",
"xweb_xhr": "1",
"zp_app_id": "10002",
"zp_product_id": "10002",
"ver": "14.0400",
"mini_ver": "14.0400",
"platform": "zhipin/mac",
"ua": '{"model":"Mac16,8","platform":"mac"}',
"scene": "1256",
"sec-fetch-site": "cross-site",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
"referer": "https://servicewechat.com/wxa8da525af05281f3/601/page-frame.html",
"accept-language": "zh-CN,zh;q=0.9",
}
class BossClient(HTTPClient):
def __init__(
self,
signer: Optional[BossSign] = None,
tunnel_proxy: Optional[str] = None,
proxy: Optional[str] = None,
proxy_pool: Optional[list[str]] = None,
timeout: int = 10,
):
super().__init__(
base_url=BASE_URL,
default_headers=BOSS_HEADERS,
tunnel_proxy=tunnel_proxy,
proxy=proxy,
proxy_pool=proxy_pool,
timeout=timeout,
)
self.signer = signer or BossSign()
def _boss_headers(self) -> dict:
return {
"mpt": self.signer.mpt,
"wt2": self.signer.wt2,
"Traceid": BossSign.generate_traceid("M-W"),
}
def post(self, path: str, body: dict, headers: Optional[dict] = None) -> tuple[int, Any]:
boss_h = self._boss_headers()
if headers:
boss_h.update(headers)
return super().post(path, body, boss_h)
def get(self, path: str, params: Optional[dict] = None, headers: Optional[dict] = None) -> tuple[int, Any]:
boss_h = self._boss_headers()
if headers:
boss_h.update(headers)
return super().get(path, params, boss_h)
def batch(self, sub_reqs: list[dict]) -> tuple[int, Any]:
body = {"subReqs": sub_reqs, "appId": 10002}
return self.post(
"/wapi/batch/requests",
body,
headers={"content-type": "application/json"},
)
def create_client(
signer: Optional[BossSign] = None,
tunnel_proxy: Optional[str] = None,
proxy: Optional[str] = None,
proxy_pool: Optional[list[str]] = None,
) -> BossClient:
return BossClient(signer=signer, tunnel_proxy=tunnel_proxy, proxy=proxy, proxy_pool=proxy_pool)