案例地址土地市场网郑重声明本文只做学习研究分享若有人用文章技术做出不法行为与本人无关如有侵权联系作者立即删除找加密参数打开供应计划页面先把它抓下来按 F12 打开开发者工具点Network网络面板勾上Fetch/XHR只看接口请求过滤掉图片那些然后点页面上的“查询”面板里就会列出这期间发的请求。数据是这条接口给的POST https://api.landchina.com/tGyjh/plan/list点开它、切到Headers往下看Request Headers请求头除了常规的User-Agent、Referer还多了一个Hash值是 64 个十六进制字符。64 位正好是 SHA256 的长度先记下这个直觉——目标就是搞清这串Hash怎么来的。这是我刚抓到的真实请求头POST https://api.landchina.com/tGyjh/plan/list Hash: 7c4a8dfb61c218f51d1968b1f4aa13ecd0a13adedc80c98f61594a2a527193dc User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36定位加密位置先说“去哪儿看代码”这一步很多新手会卡我一步一步来。第一步认识 Sources。按 F12 打开开发者工具点最上面一排的Sources。这个面板就是“这个网页加载过的所有 JS 文件”的仓库左边是文件目录树点哪个文件右边就显示它的源码。第二步给接口下 XHR 断点。在 Sources 右边找到XHR/fetch Breakpoints对接口请求下断点的地方点填plan/list。再点一次页面的“查询”请求就会停在“发出去之前”——这时你能看到它到底带了什么、是谁调它发的。看图右上 ① 是“Paused on XHR or fetch”的暂停提示右边 ② 的Scope里o就是这次要发的请求体{pageNum:1,...}下面 ③ 是Call Stack调用栈从下往上是onSubmit → _planList → y(app.3b86a958.js) → request → chunk-vendors...js。第三步别在栈里硬跟去拦截器找。栈顶那几层chunk-vendors、request、xhr全是 axios 自己发请求的代码。这说明Hash不是在这一步算的而是在请求真正发出之前就被 axios 的“请求拦截器”塞进 headers 了。所以顺着栈往上找到业务代码那一层app.js里的y或者直接去拦截器里搜。第四步搜关键词定位到那一行。拦截器既然跟 UA 有关那它一定会读userAgent。按 CtrlShiftF 全局搜t[Hash]在app.3b86a958.js里命中这段图底部 Search 面板里那行就是原文我把命中的t[Hash]圈出来了t[Hash] o(navigator.userAgent (new Date).getDate() a[a.length - 1]);翻译成人话a e.url.split(/)把接口地址按/切开a[a.length-1]就是最后一段这里是list(new Date).getDate()是今天的“几号”1~31没有前导零把UA 几号 list三段拼一起当“种子”交给o就是 crypto-js 里的 SHA256算一下结果塞进请求头Hash。顺便说一句开发者忘了删那句console.log(种子)——等于把答案直接打印给你看。这种漏网细节遇到了别客气顺着它验证最省事。复现加密逻辑相互证明先别信它一面之词本地按这个规则拼种子算一遍跟抓包看到的Hash对一下import hashlib UA (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36) seed UA 25 list # 今天 25 号 print(hashlib.sha256(seed.encode()).hexdigest())真实跑出来的对齐结果local SHA256 : 7c4a8dfb61c218f51d1968b1f4aa13ecd0a13adedc80c98f61594a2a527193dc site Hash : 7c4a8dfb61c218f51d1968b1f4aa13ecd0a13adedc80c98f61594a2a527193dc MATCH : True两边一字不差标准 SHA256确认无误。完整复现import hashlib from datetime import datetime import requests UA (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/155.0.0.0 Safari/537.36) API_URL https://api.landchina.com/tGyjh/plan/list def build_hash(url): # UA 当日几号 URL末段 → SHA256 seed UA str(datetime.now().day) url.split(/)[-1] return hashlib.sha256(seed.encode(utf-8)).hexdigest() def fetch_plan_list(page_num1, page_size10): headers {Hash: build_hash(API_URL), Origin: https://www.landchina.com, Referer: https://www.landchina.com/, User-Agent: UA} payload {pageNum: page_num, pageSize: page_size, startDate: , endDate: } r requests.post(API_URL, headersheaders, jsonpayload, timeout10) r.raise_for_status() return r.json() if __name__ __main__: data fetch_plan_list(page_num1, page_size10) body data.get(data) or {} print(code:, data.get(code), | msg:, data.get(msg)) print(总数:, body.get(total), | 本页:, len(body.get(list) or [])) for item in (body.get(list) or [])[:3]: print( -, item.get(biaoti), |, item.get(xzqFullName))结果本机刚跑的今天code: 200 | msg: 操作成功 总数: 1419 | 本页: 10 - 汾阳市2026年度国有建设用地供应计划 | 山西省吕梁市汾阳市 - 宁南县2026年度国有建设用地供应计划 | 四川省凉山彝族自治州宁南县 - 荔波县2026年度国有建设用地供应计划 | 贵州省黔南布依族苗族自治州荔波县踩坑UA 必须和你请求头里真正发出去的那串一字不差差一个字符 Hash 就对不上日期只取“几号”1~31不是完整日期而且用的是电脑本地时间过了零点或换了时区会变最后一段是list换别的接口时把新地址传进build_hash就行规则不用改定位时别在调用栈里硬跟 axios 那几层看到栈顶都是chunk-vendors/request就该知道是拦截器干的直接去搜userAgent或t[Hash]更快。小结这篇不难就是个“请求头藏了个 SHA256”。套路记住两点看到请求头里莫名多出一串固定长度的十六进制先猜hash(UA 时间 接口名)这种拼接跟栈发现栈顶都是 axios 自己的代码时别硬跟去请求拦截器里找。如有问题请及时提出加油加油。
阅读完成 · 觉得有帮助?