find_global_state.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. """暴力提取:从window.__INITIAL_STATE__或Vue根组件拿笔记ID"""
  2. import json, time, websocket, urllib.request
  3. tabs = json.loads(urllib.request.urlopen("http://127.0.0.1:9222/json").read())
  4. ws_url = None
  5. for t in tabs:
  6. if "creator.xiaohongshu.com" in t.get("url", ""):
  7. ws_url = t["webSocketDebuggerUrl"]
  8. break
  9. ws = websocket.create_connection(ws_url, timeout=15)
  10. msg_id = 0
  11. def send_cmd(method, params=None):
  12. global msg_id
  13. msg_id += 1
  14. ws.send(json.dumps({"id": msg_id, "method": method, "params": params or {}}))
  15. while True:
  16. resp = json.loads(ws.recv())
  17. if resp.get("id") == msg_id:
  18. return resp.get("result", {})
  19. send_cmd("Page.navigate", {"url": "https://creator.xiaohongshu.com/new/note-manager"})
  20. time.sleep(6)
  21. # 暴力搜索window对象中所有包含noteId的属性
  22. js = """
  23. (function() {
  24. var results = [];
  25. // 搜索window上的全局状态
  26. var keys = ['__INITIAL_STATE__', '__NUXT__', '__APP_DATA__', '__PRELOADED_STATE__'];
  27. for (var i = 0; i < keys.length; i++) {
  28. if (window[keys[i]]) {
  29. results.push({source: keys[i], type: typeof window[keys[i]]});
  30. }
  31. }
  32. // 搜索Vue实例
  33. var app = document.querySelector('#app') || document.querySelector('[id]');
  34. if (app && app.__vue__) {
  35. results.push({source: 'vue_root', type: 'found'});
  36. // 遍历vue data
  37. try {
  38. var vueData = JSON.stringify(app.__vue__.$data || {}).substring(0, 2000);
  39. results.push({source: 'vue_data', data: vueData});
  40. } catch(e) {
  41. results.push({source: 'vue_data_error', msg: e.message});
  42. }
  43. }
  44. // 搜索所有__vue__实例
  45. var vueEls = document.querySelectorAll('*');
  46. var vueCount = 0;
  47. for (var j = 0; j < vueEls.length && vueCount < 3; j++) {
  48. if (vueEls[j].__vue__) {
  49. vueCount++;
  50. try {
  51. var d = vueEls[j].__vue__.$data;
  52. var str = JSON.stringify(d);
  53. if (str.indexOf('noteId') >= 0 || str.indexOf('note_id') >= 0) {
  54. results.push({source: 'vue_with_noteId', data: str.substring(0, 3000)});
  55. }
  56. } catch(e) {}
  57. }
  58. }
  59. // 搜索React root
  60. var rootEl = document.getElementById('root') || document.getElementById('app');
  61. if (rootEl) {
  62. var rKey = Object.keys(rootEl).find(function(k) { return k.startsWith('__reactContainer') || k.startsWith('__reactFiber'); });
  63. if (rKey) {
  64. results.push({source: 'react_root', key: rKey});
  65. }
  66. }
  67. // 最后手段:搜索所有script标签中的JSON数据
  68. document.querySelectorAll('script').forEach(function(s) {
  69. var text = s.textContent || '';
  70. if (text.indexOf('noteId') >= 0 || text.indexOf('note_id') >= 0) {
  71. var match = text.match(/"noteId"\s*:\s*"([a-f0-9]+)"/g);
  72. if (match) {
  73. results.push({source: 'script_tag', noteIds: match.slice(0, 10)});
  74. }
  75. }
  76. });
  77. return JSON.stringify(results, null, 2);
  78. })()
  79. """
  80. result = send_cmd("Runtime.evaluate", {"expression": js, "returnByValue": True})
  81. val = result.get("result", {}).get("value", "")
  82. with open(r"C:\code\cfc\运营文案\小红书发布\_process_scripts\global_state.txt", "w", encoding="utf-8") as f:
  83. f.write(val)
  84. print("DONE")
  85. ws.close()