小红书数据采集终极指南:基于Python的高效反爬虫技术实现与实战应用
【免费下载链接】xhs 基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/ 项目地址: https://gitcode.com/gh_mirrors/xh/xhs
在小红书这个拥有数亿用户的生活方式分享平台上,海量的公开数据蕴含着巨大的商业价值和研究意义。然而,平台日益严格的反爬虫机制让传统的数据采集方法举步维艰。xhs项目正是为了解决这一技术难题而生的Python工具库,通过深度逆向工程和智能签名算法,为开发者和数据分析师提供了稳定、高效的小红书数据采集解决方案。
为什么需要专业的小红书数据采集工具?
小红书作为中国领先的社交媒体平台,其数据采集面临着多重挑战:
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:签名失败怎么办?
解决方案:
# 重新获取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被封禁如何处理?
解决方案:
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:数据获取不完整
解决方案:
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
🔮 未来发展与扩展建议
技术演进方向
生态扩展计划
📋 最佳实践总结
开发环境配置
# 创建虚拟环境
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),仅供参考


-171主机测评](https://www.171host.com/wp-content/uploads/2026/09/20260909052429-6aa0ed8d3dff8-220x150.jpg)
