轻松聘
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

76 lines
3.6 KiB

import json, urllib.request, urllib.error
BASE = "https://job.youthome.com.cn/api/v1"
def req(method, path, token=None, body=None):
url = BASE + path
data = json.dumps(body).encode() if body is not None else None
r = urllib.request.Request(url, data=data, method=method)
r.add_header("Content-Type", "application/json")
if token:
r.add_header("Authorization", "Bearer " + token)
try:
with urllib.request.urlopen(r, timeout=20) as resp:
raw = resp.read().decode()
status = resp.status
except urllib.error.HTTPError as e:
raw = e.read().decode(errors="replace")
status = e.code
except Exception as e:
return None, str(e), None
try:
j = json.loads(raw)
except Exception:
return status, raw[:200], None
return status, j, raw
# 1) login
s, j, _ = req("POST", "/auth/password/login", body={"phone": "19900009021", "password": "ZhilaiTest!2026#A"})
token = (j or {}).get("data", {}).get("accessToken") if j else None
print("LOGIN:", s, "hasToken=", bool(token), "role=", (j or {}).get("data", {}).get("role"), "expiresIn=", (j or {}).get("data", {}).get("en"))
print("="*100)
# 2) validate ID-less GET endpoints (student token)
idless = [
("GET", "/jobs", "fetchJobList(ALIGNED)"),
("GET", "/offers/compare", "fetchOfferCompareData(ALIGNED)"),
("GET", "/profile/me", "fetchUserProfile(ALIGNED)"),
("GET", "/conversations", "fetchConversations(WRONG->REAL /conversations)"),
("GET", "/notifications", "fetchNotifications(WRONG->REAL /notifications)"),
("GET", "/notifications/unread-count", "bonus real"),
("GET", "/interviews/me", "fetchInterviews(WRONG->REAL /interviews/me)"),
("GET", "/jobs/favorites", "fetchFavorites(WRONG->REAL /jobs/favorites)"),
("GET", "/profile/me/career-progress", "fetchJobProgress(WRONG->REAL /profile/me/career-progress)"),
("GET", "/profile/me/preferences", "fetchJobPreference(WRONG->REAL /profile/me/preferences)"),
("GET", "/profile/me/resume", "fetchResume(WRONG->REAL /profile/me/resume)"),
("GET", "/profile/me/candidate-scoring", "bonus real"),
("GET", "/applications/me", "bonus real /applications/me"),
("GET", "/assessments/me", "bonus real /assessments/me"),
("GET", "/abilities/me", "bonus real /abilities/me"),
]
for m, p, label in idless:
s, j, _ = req(m, p, token)
code = (j or {}).get("code") if isinstance(j, dict) else None
data = (j or {}).get("data")
dtype = type(data).__name__
keys = list(data.keys())[:12] if isinstance(data, dict) else (f"len={len(data)}" if isinstance(data, list) else None)
print(f"{m:4} {p:42} [{label}]")
print(f" http={s} code={code} data_type={dtype} sample={keys}")
print("="*100)
# 3) ID-needing endpoints: best-effort with placeholder id (status ambiguous if 404)
idneed = [
("GET", "/jobs/1", "fetchJobDetail(ALIGNED) needs jobId"),
("GET", "/jobs/1/reviews", "fetchEmployeeReviews(ALIGNED)"),
("GET", "/jobs/1/competition-ranking", "fetchRankData(WRONG->REAL)"),
("GET", "/jobs/1/match", "fetchMatchResult alt"),
("GET", "/conversations/1", "fetchConversation(WRONG->REAL /conversations/{id})"),
("GET", "/applications/1/match", "fetchMatchResult(WRONG->REAL)"),
("GET", "/company/candidates/1", "fetchCandidateDetail(WRONG->REAL, ENTERPRISE role)"),
("GET", "/interviews/1/score", "fetchInterviewScore(WRONG->REAL)"),
]
for m, p, label in idneed:
s, j, _ = req(m, p, token)
code = (j or {}).get("code") if isinstance(j, dict) else None
msg = (j or {}).get("message") if isinstance(j, dict) else None
print(f"{m:4} {p:42} [{label}] http={s} code={code} msg={msg}")