xhshow

repository·master·Indexed 21 days ago

https://github.com/cloxl/xhshow

A Python library for generating request headers and signatures (such as x-s, x-s-common, and x-rap-param) required for interacting with Xiaohongshu (Little Red Book) APIs. It supports both XYS and XYW signature formats, provides utilities for generating search IDs and cookies (a1, web_id), and includes a SessionManager to simulate realistic user sessions and browser fingerprints.

Tokens
4.2K
Snippets
14
Records
18
Agent score
76%

What's inside xhshow

  1. Manage sessions for improved stability

    master

    The SessionManager (experimental) maintains stateful signing parameters, such as a fixed page load timestamp and a monotonically increasing counter. This simulates continuous user operations and may improve long-term stability.

    For multi-account usage, create a unique SessionManager instance for each account and reuse it across multiple requests for that account.

    from xhshow import Xhshow, SessionManager
    
    client = Xhshow()
    session = SessionManager()
    
    # Reuse the same session object across multiple requests
    headers = client.sign_headers_get(
        uri="/api/sns/web/v1/user_posted",
        cookies=cookies,
        params={"num": "30"},
        session=session,
    )
  2. Generate request headers for GET and POST requests

    master

    Use the Xhshow client to generate all necessary headers (including x-s, x-s-common, x-t, etc.) for Xiaohongshu API requests.

    • For GET requests, use sign_headers_get. You can pass a full URL or just the URI path; the library will automatically extract the path.
    • For POST requests, use sign_headers_post. Instead of params, use the payload argument to pass the request body.
    from xhshow import Xhshow
    import requests
    
    client = Xhshow()
    cookies = {"a1": "...", "web_session": "...", "webId": "..."}
    
    # GET Request
    headers = client.sign_headers_get(
        uri="https://edith.xiaohongshu.com/api/sns/web/v1/user_posted",
        cookies=cookies,
        params={"num": "30", "cursor": "", "user_id": "123"},
    )
    
    # POST Request
    headers = client.sign_headers_post(
        uri="https://edith.xiaohongshu.com/api/sns/web/v1/login",
        cookies=cookies,
        payload={"username": "test", "password": "123456"},
    )
  3. Configure xhshow with CryptoConfig

    master

    You can customize the cryptographic behavior of the client using CryptoConfig. Use the .with_overrides() method to set custom values for internal parameters like X3_PREFIX or sequence value ranges.

    from xhshow import CryptoConfig, Xhshow
    
    config = CryptoConfig().with_overrides(
        X3_PREFIX="custom_",
        SEQUENCE_VALUE_MIN=20,
        SEQUENCE_VALUE_MAX=60,
    )
    client = Xhshow(config=config)
  4. Use the Xhshow client to generate request headers

    master

    The Xhshow class is the primary entrypoint for generating all necessary Xiaohongshu request headers, including signatures (x-s), common signatures (x-s-common), and trace IDs.

    Depending on the API endpoint, you may need to choose between two signature formats:

    • xys: The traditional format (default), suitable for most non-data APIs.
    • xyw: Required for data-fetching APIs (e.g., user_posted, otherinfo) that return HTTP 406 when using the xys format.

    For endpoints like feed, search, or note publishing, enable x_rap=True to generate the x-rap-param header.

    from xhshow import Xhshow
    
    client = Xhshow()
    cookies = {"a1": "your_a1_value", "web_session": "..."}
    
    # Example: GET request for data-fetching API using 'xyw' format
    headers = client.sign_headers_get(
        uri="/api/sns/web/v1/user_posted",
        cookies=cookies,
        params={"num": "30"},
        sign_format="xyw"
    )
    
    # Example: POST request with x-rap-param enabled
    headers = client.sign_headers_post(
        uri="/api/sns/web/v1/feed",
        cookies=cookies,
        payload={"source_note_id": "..."},
        x_rap=True
    )
  5. Generate individual header fields

    master

    If you do not need the full header set, you can generate specific fields individually:

    x-s Signatures

    • sign_xs_get(uri, a1_value, params=None, timestamp=None): Generates x-s for GET requests. Requires a1_value.
    • sign_xs_post(uri, a1_value, payload=None, timestamp=None): Generates x-s for POST requests. Requires a1_value.

    x-s-common

    • sign_xsc(cookie_dict): Generates x-s-common. Accepts a dictionary or a string of cookies.

    Other Fields

    • get_x_t(timestamp=None): Returns a millisecond timestamp. Use the timestamp argument to ensure consistency across all headers.
    • get_b3_trace_id(): Returns a 16-character trace ID.
    • get_xray_trace_id(timestamp=None): Returns a 32-character trace ID.

    Note on Timestamps: To ensure all header fields use the exact same time, generate a single timestamp using time.time() and pass it to the relevant methods.

    import time
    
    ts = time.time()
    # Use the same timestamp for all fields to ensure consistency
    x_s = client.sign_xs_get(uri="...", a1_value="...", params={"num": "30"}, timestamp=ts)
    x_t = client.get_x_t(timestamp=ts)
    x_xray = client.get_xray_trace_id(timestamp=int(ts * 1000))
  6. Generate x-rap-param for risk control headers

    master

    Certain interfaces (feed, search, note publishing) require an additional x-rap-param header. To generate this, set x_rap=True when calling the signing methods.

    • x_rap: Boolean flag to enable x-rap-param generation. The algorithm is based on the API path and the request body.
    • user_id: (Optional) If provided, xy-direction is calculated using MurmurHash3 on the user_id. If omitted, a random value is used.
    headers = client.sign_headers_post(
        uri="https://edith.xiaohongshu.com/api/sns/web/v1/feed",
        cookies=cookies,
        payload={"source_note_id": "..."},
        x_rap=True,           # Generates x-rap-param
        user_id="5ff...",     # Optional: used for xy-direction calculation
    )
  7. Generate search and account parameters

    master

    The Xhshow client provides methods to generate specific parameters used in search and account-related APIs:

    • get_search_id(): Returns the search interface search_id (base36).
    • get_search_request_id(): Returns the search interface request_id in the format "{random}-{ts_ms}".
    • Xhshow.generate_a1(): Generates a 52-character a1 cookie.
    • Xhshow.generate_web_id(a1): Generates a 32-character hex web_id based on a provided a1 value.
  8. Manage simulated user sessions with SessionManager

    master

    To generate realistic signatures that mimic a real user session, use the SessionManager class. It maintains evolving state counters (like sequence_value and window_props_length) that change over time to simulate user activity between requests.

    Key Workflow

    1. Initialize: Create a SessionManager instance. You can optionally pass a CryptoConfig object to customize the initial ranges for session parameters.
    2. Retrieve State: Call get_current_state(uri) before each signing operation. This method automatically updates the internal session counters and calculates the uri_length based on the provided URI.
    3. State Persistence: The manager is designed to be long-lived; do not re-instantiate it for every request, as the counters must evolve across multiple requests within the same logical session.
    from xhshow.session import SessionManager
    
    # Initialize the manager
    manager = SessionManager()
    
    # For each request, get the current state using the target URI
    uri = "https://example.com/api/data"
    state = manager.get_current_state(uri)
    
    # Use the state (SignState) for your signing logic
    print(f"Timestamp: {state.page_load_timestamp}")
    print(f"Sequence: {state.sequence_value}")
    print(f"URI Length: {state.uri_length}")
  9. Decrypt XYS_ and x3 signatures

    master

    If you have an existing signature, you can decrypt it using the following methods:

    • decode_xs(xs_signature): Decrypts a complete XYS_ signature and returns the underlying dictionary containing x0, x1, x2, x3, and x4 fields.
    • decode_x3(x3_signature): Decrypts a Base64 encoded x3 signature and returns the original bytearray.

    Both methods automatically handle the removal of their respective prefixes (XYS_ or the configured X3_PREFIX).

  10. Update an existing fingerprint with new cookies or URL

    master

    The update method allows you to modify an existing fingerprint dictionary in-place. This is necessary when the user's session state changes (e.g., a new cookie is set or the user navigates to a different URL).

    It specifically updates the following fields:

    • x39: Resets to 0.
    • x44: Updates to the current timestamp (milliseconds).
    • x57: Updates the serialized cookie string.
    • x66: Updates the referer and location within the nested dictionary.
    # Updates the 'fp' dictionary directly
    generator.update(fp, updated_cookies, current_url)
  11. Generate XYW_ signatures with sign_xyw

    master

    The sign_xyw method generates the XYW_ format signature using AES-128-CBC encryption. This format is mandatory for specific data-fetching APIs that reject the standard XYS_ format with an HTTP 406 error.

    Parameters:

    • method: "GET" or "POST".
    • uri: The request URI or full URL.
    • a1_value: The a1 value from cookies.
    • xsec_appid: Application identifier (defaults to xhs-pc-web).
    • payload: Request parameters (GET params or POST body).
    • timestamp: Unix timestamp in seconds (defaults to current time).