fetch_comments_api.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. """用页面cookie调评论API获取每篇笔记的评论"""
  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=30)
  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(5)
  21. # 拦截评论API
  22. send_cmd("Network.enable")
  23. # 导航到坦白局笔记详情(触发评论API加载)
  24. # 先尝试直接调评论API
  25. note_ids = [
  26. ("坦白局", "6a82ca500000000025004062"),
  27. ("D27教育博主", "6a81a53d000000000600738e"),
  28. ]
  29. all_comments = {}
  30. for name, nid in note_ids:
  31. js = f"""
  32. (async function() {{
  33. try {{
  34. // 尝试多种评论API端点
  35. var urls = [
  36. '/api/galaxy/creator/note/comment?noteId={nid}&cursor=&num=20',
  37. '/api/galaxy/v2/creator/note/comment?noteId={nid}&cursor=&num=20',
  38. '/api/galaxy/creator/comment/list?noteId={nid}&cursor=&num=20',
  39. '/api/galaxy/creator/note/comments?noteId={nid}&cursor=&num=20'
  40. ];
  41. var results = [];
  42. for (var i = 0; i < urls.length; i++) {{
  43. try {{
  44. var r = await fetch(urls[i], {{credentials: 'include'}});
  45. var text = await r.text();
  46. if (text.indexOf('"success":true') >= 0 || text.indexOf('"code":0') >= 0) {{
  47. results.push({{url: urls[i], data: text.substring(0, 5000)}});
  48. }}
  49. }} catch(e) {{}}
  50. }}
  51. if (results.length === 0) {{
  52. // 也试试edith域名
  53. var edith_urls = [
  54. 'https://edith.xiaohongshu.com/api/sns/web/comment/page?note_id={nid}&cursor=&top_comment_id=&image_formats=jpg,webp,avif&xsec_token=YBieUL8uRjxi1dmXwcv1fHXDs3jL1VSMg8urb7O07P_uc='
  55. ];
  56. for (var j = 0; j < edith_urls.length; j++) {{
  57. try {{
  58. var r2 = await fetch(edith_urls[j], {{credentials: 'include'}});
  59. var t2 = await r2.text();
  60. results.push({{url: edith_urls[j], data: t2.substring(0, 5000)}});
  61. }} catch(e) {{}}
  62. }}
  63. }}
  64. return JSON.stringify(results);
  65. }} catch(e) {{ return 'ERR:' + e.message; }}
  66. }})()
  67. """
  68. ws.send(json.dumps({"id": 300 + note_ids.index((name, nid)), "method": "Runtime.evaluate", "params": {"expression": js, "returnByValue": True, "awaitPromise": True}}))
  69. for i in range(len(note_ids)):
  70. for _ in range(30):
  71. resp = json.loads(ws.recv())
  72. rid = resp.get("id", 0)
  73. if rid >= 300 and rid < 300 + len(note_ids):
  74. val = resp.get("result", {}).get("result", {}).get("value", "")
  75. name = note_ids[rid - 300][0]
  76. with open(rf"C:\code\cfc\运营文案\小红书发布\_process_scripts\comments_{name}.txt", "w", encoding="utf-8") as f:
  77. f.write(val)
  78. print(f"Saved comments for {name}")
  79. break
  80. ws.close()