Extracting and Analyzing Xiaohongshu Comment Data

The comment data for analysis includes user nickname, user ID, comment level, and comment content.

Data Extraction Process

The target content is retrieved via XHR requests, specifically through the comment endpoint. Pagination is managed using a cursor parameter. The logic for constructing the request URL is as follows:

def get_comment_url(note_id, cursor=None, page=1):
    base_url = 'https://edith.xiaohongshu.com/api/sns/web/v2/comment/page'
    query_params = {
        'note_id': note_id,
        'top_comment_id': '',
        'image_formats': 'jpg,webp,avif'
    }
    
    if page == 1:
        query_params['cursor'] = ''
    else:
        print("[INFO] Fetching next page")
        query_params['cursor'] = cursor
    
    # Construct the full URL with query parameters
    from urllib.parse import urlencode
    return f"{base_url}?{urlencode(query_params)}"

# Example usage for parsing the response and getting the next cursor
response_data = json.loads(json_text)
next_cursor_token = response_data.get('data', {}).get('cursor')
has_more_data = response_data.get('data', {}).get('has_more', False)

To determine if data extraction is complete, check the boolean value of has_more in the API response. A value of True indicates more comments are available.

Optimizing Data Collection

To improve efficiency, implement concurrent requests. Use a session management approach to handle multiple requests simultaneously.

import asyncio
import aiohttp

async def fetch_page(session, url):
    async with session.get(url) as resp:
        return await resp.json()

async def gather_comments(note_id, initial_cursor=''):
    async with aiohttp.ClientSession() as session:
        all_comments = []
        next_cursor = initial_cursor
        has_more = True
        
        while has_more:
            url = get_comment_url(note_id, cursor=next_cursor, page=2 if next_cursor else 1)
            page_data = await fetch_page(session, url)
            
            # Extract comments from the current page
            current_comments = page_data.get('data', {}).get('comments', [])
            all_comments.extend(process_comments(current_comments))
            
            # Update pagination state
            next_cursor = page_data.get('data', {}).get('cursor', '')
            has_more = page_data.get('data', {}).get('has_more', False)
        
        return all_comments

def process_comments(comment_list):
    processed = []
    for c in comment_list:
        processed.append({
            'nickname': c.get('user', {}).get('nickname'),
            'user_id': c.get('user', {}).get('user_id'),
            'level': c.get('level'),
            'content': c.get('content')
        })
    return processed

Tags: data-analysis web-scraping xiaohongshu API python

Posted on Tue, 03 Nov 2026 16:24:01 +0000 by Vball