news 2026/8/5 9:29:57

小红书数据采集终极指南:基于Python的高效反爬虫技术实现与实战应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小红书数据采集终极指南:基于Python的高效反爬虫技术实现与实战应用

小红书数据采集终极指南:基于Python的高效反爬虫技术实现与实战应用

【免费下载链接】xhs基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/项目地址: https://gitcode.com/gh_mirrors/xh/xhs

在小红书这个拥有数亿用户的生活方式分享平台上,海量的公开数据蕴含着巨大的商业价值和研究意义。然而,平台日益严格的反爬虫机制让传统的数据采集方法举步维艰。xhs项目正是为了解决这一技术难题而生的Python工具库,通过深度逆向工程和智能签名算法,为开发者和数据分析师提供了稳定、高效的小红书数据采集解决方案。

为什么需要专业的小红书数据采集工具?

小红书作为中国领先的社交媒体平台,其数据采集面临着多重挑战:

  1. 复杂的签名机制:小红书采用JavaScript混淆的动态签名算法,每次请求都需要生成特定的x-s和x-t签名
  2. 严格的反爬虫检测:包括IP限制、频率控制、浏览器指纹检测等多重防护
  3. 动态加载技术:大量内容通过AJAX动态加载,传统爬虫难以获取完整数据
  4. 数据格式复杂:笔记、用户信息、评论等数据结构嵌套复杂

xhs项目通过技术手段巧妙解决了这些问题,让数据采集变得简单可靠。

🚀 快速开始:三步搭建数据采集环境

第一步:安装xhs库

# 通过pip安装xhs库 pip install xhs # 安装Playwright浏览器自动化工具 pip install playwright playwright install chromium # 下载反检测脚本 curl -O https://cdn.jsdelivr.net/gh/requireCool/stealth.min.js/stealth.min.js

第二步:获取小红书Cookie

要使用xhs库,你需要获取小红书的登录Cookie。打开浏览器登录小红书后,按F12打开开发者工具,在Application或Storage标签页中找到Cookie,复制a1、web_session和webId三个关键字段。

第三步:编写第一个采集脚本

import json from xhs import XhsClient # 初始化客户端 cookie = "your_cookie_here" xhs_client = XhsClient(cookie) # 获取用户信息 user_info = xhs_client.get_user_info("用户ID") print(f"用户昵称: {user_info.get('nickname')}") print(f"粉丝数量: {user_info.get('fans_count')}") # 搜索热门内容 search_results = xhs_client.get_note_by_keyword("Python编程", page=1) print(f"搜索到 {len(search_results)} 条笔记") # 获取笔记详情 note_detail = xhs_client.get_note_by_id("笔记ID") print(f"笔记标题: {note_detail.get('title')}")

⚙️ 核心架构:如何绕过小红书的反爬虫机制

签名算法逆向工程

xhs项目的核心技术在于模拟小红书Web端的JavaScript签名算法。通过Playwright浏览器自动化,项目能够执行页面中的签名函数,生成正确的请求签名。

def sign(uri, data=None, a1="", web_session=""): """小红书签名函数实现""" for _ in range(10): try: with sync_playwright() as playwright: chromium = playwright.chromium browser = chromium.launch(headless=True) browser_context = browser.new_context() # 加载反检测脚本 browser_context.add_init_script(path="stealth.min.js") context_page = browser_context.new_page() context_page.goto("https://www.xiaohongshu.com") # 设置cookie browser_context.add_cookies([ {'name': 'a1', 'value': a1, 'domain': ".xiaohongshu.com", 'path': "/"} ]) context_page.reload() sleep(1) # 执行签名函数 encrypt_params = context_page.evaluate( "([url, data]) => window._webmsxyw(url, data)", [uri, data] ) return { "x-s": encrypt_params["X-s"], "x-t": str(encrypt_params["X-t"]) } except Exception: continue raise Exception("签名重试多次失败")

服务端签名方案

对于生产环境,xhs项目提供了服务端签名方案,将签名计算独立为服务,客户端只需调用API即可:

# 启动签名服务 docker run -it -d -p 5005:5005 reajason/xhs-api:latest # 客户端使用签名服务 from xhs import XhsClient def sign_from_server(uri, data=None): """从签名服务获取签名""" import requests response = requests.post( "http://localhost:5005/sign", json={"uri": uri, "data": data} ) return response.json() xhs_client = XhsClient(cookie, sign=sign_from_server)

📊 数据采集功能全解析

用户数据采集

# 获取用户基本信息 user_info = xhs_client.get_user_info("用户ID") # 获取用户发布的笔记 user_notes = xhs_client.get_user_notes("用户ID", page=1, limit=20) # 获取用户收藏的笔记 user_collects = xhs_client.get_user_collect_notes("用户ID") # 获取用户点赞的笔记 user_likes = xhs_client.get_user_like_notes("用户ID") # 获取用户关注列表 following_list = xhs_client.get_following("用户ID") # 获取用户粉丝列表 fans_list = xhs_client.get_followers("用户ID")

内容搜索与过滤

xhs库支持多种搜索方式和过滤条件:

from xhs import SearchSortType, SearchNoteType # 按关键词搜索 results = xhs_client.get_note_by_keyword( keyword="美食探店", sort_type=SearchSortType.MOST_POPULAR, # 按热度排序 note_type=SearchNoteType.ALL, # 所有类型 page=1 ) # 获取首页推荐内容 home_feed = xhs_client.get_home_feed(feed_type="homefeed_recommend")

笔记详情与互动数据

# 获取笔记完整信息 note_detail = xhs_client.get_note_by_id("笔记ID") # 获取笔记评论 comments = xhs_client.get_note_comments("笔记ID", cursor="") # 获取笔记子评论 sub_comments = xhs_client.get_note_sub_comments("笔记ID", "父评论ID") # 点赞笔记 xhs_client.like_note("笔记ID") # 收藏笔记 xhs_client.collect_note("笔记ID") # 发表评论 xhs_client.comment_note("笔记ID", "评论内容")

🔧 高级功能与性能优化

批量数据处理

from concurrent.futures import ThreadPoolExecutor, as_completed import time def batch_collect_user_notes(user_ids, max_workers=3): """批量采集多个用户的笔记""" results = {} with ThreadPoolExecutor(max_workers=max_workers) as executor: future_to_user = { executor.submit(xhs_client.get_user_notes, user_id): user_id for user_id in user_ids } for future in as_completed(future_to_user): user_id = future_to_user[future] try: notes = future.result() results[user_id] = notes print(f"用户 {user_id} 的笔记采集完成,共 {len(notes)} 条") except Exception as e: print(f"用户 {user_id} 采集失败: {e}") # 控制请求频率 time.sleep(1) return results

智能频率控制

import time from collections import deque from threading import Lock class RateLimiter: """智能请求频率控制器""" def __init__(self, max_requests=20, period=60): self.max_requests = max_requests self.period = period self.request_times = deque() self.lock = Lock() def wait_if_needed(self): """根据请求频率决定是否等待""" with self.lock: now = time.time() # 清理过期请求记录 while self.request_times and now - self.request_times[0] > self.period: self.request_times.popleft() # 检查是否超过频率限制 if len(self.request_times) >= self.max_requests: oldest_time = self.request_times[0] wait_time = self.period - (now - oldest_time) if wait_time > 0: time.sleep(wait_time) now = time.time() # 记录当前请求时间 self.request_times.append(now)

🎯 实战案例:构建竞品监测系统

系统架构设计

import pandas as pd from datetime import datetime, timedelta import json class CompetitorMonitor: """竞品监测系统""" def __init__(self, competitors, xhs_client): self.competitors = competitors self.xhs_client = xhs_client self.data = {} def monitor_daily(self): """每日监测任务""" results = {} for competitor in self.competitors: try: # 获取竞品最新数据 user_info = self.xhs_client.get_user_info(competitor["user_id"]) recent_notes = self.xhs_client.get_user_notes( competitor["user_id"], page=1, limit=20 ) # 计算关键指标 metrics = self.calculate_metrics(recent_notes) # 存储结果 results[competitor["name"]] = { "user_info": user_info, "recent_notes": recent_notes[:10], # 只保留最近10条 "metrics": metrics, "timestamp": datetime.now().isoformat() } print(f"竞品 {competitor['name']} 监测完成") except Exception as e: print(f"竞品 {competitor['name']} 监测失败: {e}") continue # 请求间隔 time.sleep(2) return results def calculate_metrics(self, notes): """计算内容指标""" if not notes: return {} total_likes = sum(note.get("liked_count", 0) for note in notes) total_comments = sum(note.get("comment_count", 0) for note in notes) total_collects = sum(note.get("collected_count", 0) for note in notes) return { "total_notes": len(notes), "avg_likes": total_likes / len(notes) if notes else 0, "avg_comments": total_comments / len(notes) if notes else 0, "avg_collects": total_collects / len(notes) if notes else 0, "engagement_rate": (total_likes + total_comments) / len(notes) if notes else 0 }

数据可视化分析

import matplotlib.pyplot as plt import seaborn as sns def visualize_competitor_data(data): """可视化竞品数据""" # 准备数据 competitors = list(data.keys()) avg_likes = [data[c]["metrics"]["avg_likes"] for c in competitors] avg_comments = [data[c]["metrics"]["avg_comments"] for c in competitors] engagement_rates = [data[c]["metrics"]["engagement_rate"] for c in competitors] # 创建图表 fig, axes = plt.subplots(1, 3, figsize=(15, 5)) # 平均点赞数 axes[0].bar(competitors, avg_likes, color='skyblue') axes[0].set_title('平均点赞数') axes[0].set_ylabel('点赞数') axes[0].tick_params(axis='x', rotation=45) # 平均评论数 axes[1].bar(competitors, avg_comments, color='lightgreen') axes[1].set_title('平均评论数') axes[1].set_ylabel('评论数') axes[1].tick_params(axis='x', rotation=45) # 互动率 axes[2].bar(competitors, engagement_rates, color='salmon') axes[2].set_title('互动率') axes[2].set_ylabel('互动率') axes[2].tick_params(axis='x', rotation=45) plt.tight_layout() plt.savefig('competitor_analysis.png', dpi=300, bbox_inches='tight') plt.show()

🛡️ 异常处理与稳定性保障

完善的异常处理机制

from xhs.exception import DataFetchError, IPBlockError, SignError, NeedVerifyError def safe_xhs_request(func, *args, **kwargs): """安全的xhs请求包装器""" max_retries = 3 retry_delay = 2 for attempt in range(max_retries): try: return func(*args, **kwargs) except IPBlockError as e: print(f"IP被封禁: {e}") # 切换到备用IP或等待 time.sleep(60 * (attempt + 1)) # 指数退避 continue except SignError as e: print(f"签名错误: {e}") # 重新获取签名或刷新cookie refresh_cookie() continue except NeedVerifyError as e: print(f"需要验证: {e}") # 触发人工验证流程 trigger_human_verification() break except DataFetchError as e: print(f"数据获取失败: {e}") time.sleep(retry_delay * (attempt + 1)) continue except Exception as e: print(f"未知错误: {e}") time.sleep(retry_delay * (attempt + 1)) continue raise Exception(f"请求失败,重试 {max_retries} 次后仍然失败")

代理IP池管理

import random class ProxyManager: """代理IP池管理器""" def __init__(self, proxy_list): self.proxy_list = proxy_list self.current_index = 0 self.failed_proxies = set() def get_proxy(self): """获取可用的代理""" if not self.proxy_list: return None # 尝试获取下一个代理 for _ in range(len(self.proxy_list)): proxy = self.proxy_list[self.current_index] self.current_index = (self.current_index + 1) % len(self.proxy_list) if proxy not in self.failed_proxies: return proxy # 所有代理都失败了,清空失败记录重新开始 self.failed_proxies.clear() return self.proxy_list[0] def mark_failed(self, proxy): """标记代理失败""" self.failed_proxies.add(proxy) print(f"代理 {proxy} 标记为失败") def mark_success(self, proxy): """标记代理成功""" if proxy in self.failed_proxies: self.failed_proxies.remove(proxy)

📈 性能优化策略

连接池与缓存优化

import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry class OptimizedXhsClient: """优化版的Xhs客户端""" def __init__(self, cookie, sign_func=None): self.cookie = cookie self.sign_func = sign_func # 创建优化的session self.session = requests.Session() # 配置连接池 adapter = HTTPAdapter( pool_connections=10, pool_maxsize=100, max_retries=Retry( total=3, backoff_factor=0.5, status_forcelist=[500, 502, 503, 504] ) ) self.session.mount('https://', adapter) self.session.mount('http://', adapter) # 设置请求头 self.session.headers.update({ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Accept-Encoding': 'gzip, deflate, br', 'Connection': 'keep-alive', }) # 初始化缓存 self.cache = {} self.cache_ttl = 300 # 5分钟缓存 def get_with_cache(self, key, func, *args, **kwargs): """带缓存的请求""" current_time = time.time() if key in self.cache: cached_data, timestamp = self.cache[key] if current_time - timestamp < self.cache_ttl: return cached_data # 缓存未命中或过期 result = func(*args, **kwargs) self.cache[key] = (result, current_time) return result

🚨 常见问题与解决方案

问题1:签名失败怎么办?

解决方案:

  1. 检查cookie是否过期,重新获取有效的cookie
  2. 确保a1、web_session、webId三个字段都存在
  3. 尝试增加签名函数中的sleep时间
  4. 使用服务端签名方案
# 重新获取cookie def refresh_cookie(): # 实现cookie刷新逻辑 pass # 增加签名等待时间 def sign_with_longer_wait(uri, data=None, a1="", web_session=""): # 在context_page.reload()后增加等待时间 sleep(3) # 增加到3秒

问题2:IP被封禁如何处理?

解决方案:

  1. 使用代理IP轮换
  2. 降低请求频率
  3. 实现指数退避重试机制
class SmartRetry: """智能重试机制""" def __init__(self, max_retries=5, base_delay=1): self.max_retries = max_retries self.base_delay = base_delay def execute_with_retry(self, func, *args, **kwargs): for attempt in range(self.max_retries): try: return func(*args, **kwargs) except IPBlockError: if attempt == self.max_retries - 1: raise wait_time = self.base_delay * (2 ** attempt) # 指数退避 print(f"IP被封禁,等待 {wait_time} 秒后重试") time.sleep(wait_time)

问题3:数据获取不完整

解决方案:

  1. 检查网络连接和代理设置
  2. 验证请求参数是否正确
  3. 使用分页获取完整数据
def get_all_user_notes(user_id, max_pages=10): """获取用户所有笔记(分页)""" all_notes = [] for page in range(1, max_pages + 1): try: notes = xhs_client.get_user_notes(user_id, page=page) if not notes: break all_notes.extend(notes) print(f"已获取第 {page} 页,共 {len(notes)} 条笔记") time.sleep(1) # 控制请求频率 except Exception as e: print(f"第 {page} 页获取失败: {e}") break return all_notes

🔮 未来发展与扩展建议

技术演进方向

  1. 签名算法自适应:实现签名算法的自动检测和更新
  2. AI辅助反爬:使用机器学习识别新的反爬机制
  3. 分布式架构:支持水平扩展的大规模数据采集
  4. 实时数据处理:集成流处理框架,实现实时数据分析

生态扩展计划

  1. 数据导出插件:支持导出到MySQL、PostgreSQL、MongoDB等数据库
  2. 可视化分析工具:集成数据可视化和报表生成
  3. API网关服务:提供统一的RESTful API接口
  4. 云服务平台:部署为SaaS服务,降低使用门槛

📋 最佳实践总结

开发环境配置

# 创建虚拟环境 python -m venv venv source venv/bin/activate # Linux/Mac # 或 venv\Scripts\activate # Windows # 安装依赖 pip install xhs playwright playwright install chromium # 配置环境变量 export XHS_COOKIE="your_cookie_here" export XHS_PROXY="http://proxy.example.com:8080"

生产环境部署

# Dockerfile FROM python:3.9-slim WORKDIR /app # 安装系统依赖 RUN apt-get update && apt-get install -y \ wget \ gnupg \ && rm -rf /var/lib/apt/lists/* # 安装Chrome RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list \ && apt-get update && apt-get install -y google-chrome-stable # 复制项目文件 COPY requirements.txt . COPY . . # 安装Python依赖 RUN pip install --no-cache-dir -r requirements.txt # 安装Playwright浏览器 RUN playwright install chromium # 启动服务 CMD ["python", "your_main_script.py"]

监控与日志

import logging from datetime import datetime # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(f'xhs_crawler_{datetime.now().strftime("%Y%m%d")}.log'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) class MonitoredXhsClient: """带监控的Xhs客户端""" def __init__(self, cookie, sign_func=None): self.client = XhsClient(cookie, sign=sign_func) self.logger = logger self.request_count = 0 self.error_count = 0 def get_note_by_id(self, note_id, *args, **kwargs): """带监控的获取笔记方法""" self.request_count += 1 start_time = time.time() try: result = self.client.get_note_by_id(note_id, *args, **kwargs) elapsed = time.time() - start_time self.logger.info(f"获取笔记 {note_id} 成功,耗时 {elapsed:.2f}秒") return result except Exception as e: self.error_count += 1 self.logger.error(f"获取笔记 {note_id} 失败: {str(e)}") raise

结语

xhs项目为小红书数据采集提供了一个完整、稳定、高效的解决方案。通过深度逆向工程和技术创新,它成功绕过了平台的反爬虫机制,为开发者和数据分析师打开了小红书数据宝库的大门。

无论你是进行市场研究、竞品分析、用户洞察,还是构建基于小红书数据的应用系统,xhs都能为你提供强大的技术支持。项目采用模块化设计,易于扩展和维护,同时提供了完善的异常处理和性能优化机制。

记住,技术只是工具,合理、合法、合规地使用数据才是最重要的。xhs项目鼓励开发者在遵守平台规则和相关法律法规的前提下,创造有价值的数据应用。

开始你的小红书数据采集之旅吧!🚀

【免费下载链接】xhs基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/项目地址: https://gitcode.com/gh_mirrors/xh/xhs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/5 9:29:04

AI Agent与聊天软件集成:从概念到实战的完整指南

你是不是也遇到过这样的场景&#xff1a;想用AI查个天气&#xff0c;得先打开浏览器&#xff0c;再找到某个AI助手网站&#xff0c;登录&#xff0c;输入问题&#xff0c;等待回复&#xff0c;最后还得手动把结果复制到聊天窗口发给朋友。整个过程繁琐得让人瞬间失去分享的欲望…

作者头像 李华
网站建设 2026/8/5 9:28:04

Windows多网卡UDP发送实战:路由控制与Socket编程详解

1. 项目概述&#xff1a;多网卡UDP发送的实战场景与核心挑战在服务器运维、网络应用开发或者自动化测试领域&#xff0c;我们经常会遇到一个看似简单但实际配置起来颇为棘手的需求&#xff1a;让一台运行Windows系统的机器&#xff0c;通过多个物理或虚拟网络适配器&#xff08…

作者头像 李华
网站建设 2026/8/5 9:24:58

如何用猫抓浏览器扩展轻松捕获网页上的任何媒体资源

如何用猫抓浏览器扩展轻松捕获网页上的任何媒体资源 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 还在为网页视频无法下载而烦恼吗&#xff1f;猫…

作者头像 李华
网站建设 2026/8/5 9:24:07

低代码无代码 Agent 开发工具有哪些?从意图驱动到业务闭环的深度测评

在生成式AI浪潮演进至2026年8月的当下&#xff0c;企业级AI的应用范式已发生深刻转型。单纯具备“对话”能力的Chatbot正加速向具备“执行”能力的AI Agent进化。行业核心关注点不再仅仅是模型参数的大小&#xff0c;而是如何通过低代码或无代码工具&#xff0c;将大模型能力转…

作者头像 李华
网站建设 2026/8/5 9:23:15

DeepSeek-V4-Flash API实战:从接入到错误排查的完整指南

这类新模型 API 上线&#xff0c;最值得关注的往往不是技术参数&#xff0c;而是它能不能稳定接入、成本是否真的如宣传所说、以及在实际调用时会遇到哪些“坑”。DeepSeek-V4-Flash 正式版 API 公测&#xff0c;主打一个“成本优势”&#xff0c;宣称比 GPT-5.6 Luna 单任务成…

作者头像 李华