| 1 | import configparser |
| 2 | import json |
| 3 | import pathlib |
| 4 | from time import sleep |
| 5 | |
| 6 | import requests |
| 7 | from playwright.sync_api import sync_playwright |
| 8 | |
| 9 | from conf import BASE_DIR, XHS_SERVER, LOCAL_CHROME_HEADLESS |
| 10 | |
| 11 | config = configparser.RawConfigParser() |
| 12 | config.read('accounts.ini') |
| 13 | |
| 14 | |
| 15 | def sign_local(uri, data=None, a1="", web_session=""): |
| 16 | for _ in range(10): |
| 17 | try: |
| 18 | with sync_playwright() as playwright: |
| 19 | stealth_js_path = pathlib.Path(BASE_DIR / "utils/stealth.min.js") |
| 20 | chromium = playwright.chromium |
| 21 | |
| 22 | # 如果一直失败可尝试设置成 False 让其打开浏览器,适当添加 sleep 可查看浏览器状态 |
| 23 | browser = chromium.launch(headless=LOCAL_CHROME_HEADLESS) |
| 24 | |
| 25 | browser_context = browser.new_context() |
| 26 | browser_context.add_init_script(path=stealth_js_path) |
| 27 | context_page = browser_context.new_page() |
| 28 | context_page.goto("https://www.xiaohongshu.com") |
| 29 | browser_context.add_cookies([ |
| 30 | {'name': 'a1', 'value': a1, 'domain': ".xiaohongshu.com", 'path': "/"}] |
| 31 | ) |
| 32 | context_page.reload() |
| 33 | # 这个地方设置完浏览器 cookie 之后,如果这儿不 sleep 一下签名获取就失败了,如果经常失败请设置长一点试试 |
| 34 | sleep(2) |
| 35 | encrypt_params = context_page.evaluate("([url, data]) => window._webmsxyw(url, data)", [uri, data]) |
| 36 | return { |
| 37 | "x-s": encrypt_params["X-s"], |
| 38 | "x-t": str(encrypt_params["X-t"]) |
| 39 | } |
| 40 | except Exception: |
| 41 | # 这儿有时会出现 window._webmsxyw is not a function 或未知跳转错误,因此加一个失败重试趴 |
| 42 | pass |
| 43 | raise Exception("重试了这么多次还是无法签名成功,寄寄寄") |
| 44 | |
| 45 | |
| 46 | def sign(uri, data=None, a1="", web_session=""): |
| 47 | # 填写自己的 flask 签名服务端口地址 |
| 48 | res = requests.post(f"{XHS_SERVER}/sign", |
| 49 | json={"uri": uri, "data": data, "a1": a1, "web_session": web_session}) |
| 50 | signs = res.json() |
| 51 | return { |
| 52 | "x-s": signs["x-s"], |
| 53 | "x-t": signs["x-t"] |
| 54 | } |
| 55 | |
| 56 | |
| 57 | def beauty_print(data: dict): |
| 58 | print(json.dumps(data, ensure_ascii=False, indent=2)) |
| 59 |