影刀RPA AJAX请求拦截与监听:不刷新页面也能知道数据来了 影刀RPA AJAX请求拦截不刷新页面也能知道数据来了网页采集中有个经典难题你要的数据不是页面自带的是AJAX异步加载的。你打开页面骨架先出来数据还没到。怎么知道数据什么时候到答案是在Network层面监听。这篇文章教你用影刀拦截和监听AJAX请求不必刷新页面也能精准抓取数据。什么时候需要拦截AJAX两个典型场景场景1数据通过API加载页面只是展示层。你打开一个数据看板页面上的数字是AJAX从后端接口拉过来的。你要是等页面渲染完了再去采集文本采集的其实是渲染后的文本——格式可能被处理过比如加了千分位逗号、百分比换算。直接从AJAX响应里拿原始JSON更干净。场景2需要知道数据加载完成的精确时机。页面打开后你的流程不知道该等多久。等3秒可能不够等10秒又浪费。如果能监听到那个关键的API请求完成了就能在数据到达的瞬间开始采集。方式一影刀浏览器的Network监听影刀的浏览器驱动基于Chromium支持在页面加载过程中监听网络请求。在Python节点中通过Selenium的execute_cdp_cmd方法CDP Chrome DevTools Protocol来拦截请求店群矩阵自动化突破运营极限# 在影刀Python节点中启用Network监听# 获取当前浏览器的driver对象取决于影刀的API# 此处为伪代码示意实际需要通过影刀的环境获取fromseleniumimportwebdriver# 启用Network域driver.execute_cdp_cmd(Network.enable,{})# 设置请求拦截的回调# 实际上需要通过事件监听来做简化示例但是坦白说在影刀的Python节点环境中直接操作CDP比较复杂因为影刀对浏览器实例的封装层比较厚。更实用的方式是——直接在页面上注入JS来拦截。方式二注入JS拦截XMLHttpRequest推荐在页面加载后、AJAX请求发出前注入一段JS代码来拦截所有XMLHttpRequest// 拦截XMLHttpRequest(function(){varoriginalOpenXMLHttpRequest.prototype.open;varoriginalSendXMLHttpRequest.prototype.send;// 存储拦截到的数据window.__capturedResponses[];XMLHttpRequest.prototype.openfunction(method,url){this._methodmethod;this._urlurl;returnoriginalOpen.apply(this,arguments);};XMLHttpRequest.prototype.sendfunction(body){this.addEventListener(load,function(){// 拦截目标URL的响应if(this._url.includes(/api/orders)){window.__capturedResponses.push({url:this._url,status:this.status,response:this.responseText});console.log([拦截] this._url → this.status);}});returnoriginalSend.apply(this,arguments);};})();在影刀里的使用流程1. 【打开网页】 2. 【执行JS】→ 注入上面的拦截代码 3. 正常操作页面触发AJAX请求 4. 【等待 3 秒】→ 等AJAX完成 5. 【执行JS】→ 取出拦截到的数据 var data window.__capturedResponses; return JSON.stringify(data); 6. Python节点 → 解析拦截到的JSON数据关键拦截代码必须在AJAX请求发出之前注入。如果你打开页面后数据已经加载完了再注入就晚了。正确的顺序是打开页面 → 立刻注入拦截代码 → 然后触发数据加载比如点击搜索按钮、滚动到列表区域。方式三注入JS拦截Fetch请求现代网站越来越多地使用fetchAPI 而不是传统的XMLHttpRequest。上面那段代码拦截不到fetch请求。需要额外处理// 拦截fetch(function(){varoriginalFetchwindow.fetch;window.__capturedFetchResponses[];window.fetchfunction(){varurlarguments[0];varoptionsarguments[1]||{};returnoriginalFetch.apply(this,arguments).then(function(response){// 克隆响应响应体只能读一次varcloneresponse.clone();clone.text().then(function(body){if(url.includes(/api/)){window.__capturedFetchResponses.push({url:url,status:response.status,response:body});console.log([Fetch拦截] url);}});returnresponse;});};})();注意response.clone()—— Response对象的body只能读取一次。如果你拦截了响应还要让页面正常使用必须先clone再读。方式四直接调用页面的API接口最高效这是最干净的方案。不需要拦截不需要等页面渲染——直接用Python发HTTP请求调API。找到目标API的方式F12 → Network面板 → 清空在页面上做操作搜索、翻页等看Network面板里的XHR请求找到返回了你需要的数据的那个请求右键 → Copy → Copy as cURL然后在影刀的Python节点里用requests库复现这个请求importrequests# 从浏览器Network面板复制的请求headers{Authorization:Bearer xxxxx,Content-Type:application/json,User-Agent:Mozilla/5.0 ...,}responserequests.get(https://example.com/api/orders?page1size50,headersheaders)dataresponse.json()ordersdata[data][list]print(f获取到{len(orders)}条订单数据)直接调API的优势不需要浏览器渲染速度快10倍以上拿到的是原始JSON格式干净可以翻页、筛选、排序——全部通过URL参数控制不受页面改版影响API接口通常比页面结构稳定直接调API的挑战需要解决认证问题Token、Cookie等有些API有反爬措施签名、时间戳加密等需要理解API的参数和返回结构实战案例在影刀里拦截数据看板的APItemu店群自动化报活动案例场景一个后台数据看板加载后AJAX请求获取销售额数据。需要每天自动采集这个数字。流程1. 【打开网页】→ 数据看板页面 2. 【执行JS】→ 注入XMLHttpRequest和Fetch的拦截代码 3. 【等待元素】→ 等待页面上某个关键元素出现说明页面骨架加载完了 4. 【等待 5 秒】→ 等AJAX请求完成 5. 【执行JS】→ 取出所有拦截到的API响应 var all { xhr: window.__capturedResponses || [], fetch: window.__capturedFetchResponses || [] }; return JSON.stringify(all); 6. Python节点 → 解析拦截数据提取目标字段Python节点中的解析逻辑importjson# captured_json 是从JS返回的拦截数据capturedjson.loads(captured_json)target_dataNone# 从XMLHttpRequest拦截中找foritemincaptured.get(xhr,[]):ifsales/summaryinitem[url]:target_datajson.loads(item[response])break# 如果XHR没找到从Fetch拦截中找ifnottarget_data:foritemincaptured.get(fetch,[]):ifsales/summaryinitem[url]:target_datajson.loads(item[response])breakiftarget_data:today_salestarget_data[data][total_amount]print(f今日销售额¥{today_sales})else:print(未找到目标API的响应数据)三个注意事项1. Cookie/Token同步问题。直接调API需要认证信息。如果你从浏览器里复制Cookie到Python脚本里Cookie过期了脚本就挂了。需要在Python脚本里也模拟登录流程获取Token或者定期从浏览器同步Cookie。2. API请求频率控制。直接调API比页面操作快很多但太快了会被反爬。建议每次请求间隔至少0.5-1秒。需要大批量请求时更要控制节奏。3. 拦截代码的性能影响。拦截代码会在每个请求上执行回调函数。如果页面有大量不相关的请求埋点、心跳等拦截代码会有轻微的性能开销。不过对于RPA场景来说这个开销可以忽略不计。总结能用API直接调的就不用页面采集——这是采集效率的最高境界。不得不走页面采集时注入JS拦截AJAX是知道数据什么时候到的最可靠方式。作者林焱