from flask import Flask, request, jsonify import re import requests import os from functools import wraps app = Flask(__name__) # 从环境变量获取API密钥,如果不存在则使用默认值 API_KEY = os.environ.get("XHS_API_KEY", "default_secret_key") # API密钥验证装饰器 def require_api_key(f): @wraps(f) def decorated_function(*args, **kwargs): # 从请求头获取API密钥 api_key = request.headers.get('x-api-key') # 验证API密钥 if api_key and api_key == API_KEY: return f(*args, **kwargs) else: return jsonify({"status": "error", "message": "无效的API密钥"}), 401 return decorated_function def extract_url(text): """从文本中提取小红书链接(短链接或完整链接)""" # 匹配形如 http://xhslink.com/xxxx 的短链接 short_pattern = r'http://xhslink\.com/\S+' # 匹配形如 https://www.xiaohongshu.com/discovery/item/xxx 的完整链接 full_pattern = r'https://www\.xiaohongshu\.com/\S+' # 先尝试匹配短链接 short_matches = re.findall(short_pattern, text) short_urls = [match.rstrip(',').rstrip(',').rstrip('。').rstrip('.') for match in short_matches] # 再尝试匹配完整链接 full_matches = re.findall(full_pattern, text) full_urls = [match.rstrip(',').rstrip(',').rstrip('。').rstrip('.') for match in full_matches] # 返回所有找到的链接及其类型 result = [] for url in short_urls: result.append(("short", url)) for url in full_urls: result.append(("full", url)) return result def get_redirect_url(short_url): """获取短链接重定向后的真实链接""" try: headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.9", "Connection": "keep-alive", } response = requests.get(short_url, headers=headers, allow_redirects=False) if response.status_code in [301, 302, 307]: return response.headers['Location'] else: return f"错误: 无法获取重定向链接,状态码: {response.status_code}" except Exception as e: return f"错误: 请求失败 - {str(e)}" def convert_links(text): """转换文本中的所有小红书链接""" urls = extract_url(text) if not urls: return {"status": "error", "message": "未找到小红书链接", "results": []} results = [] for url_type, url in urls: if url_type == "short": real_url = get_redirect_url(url) results.append({ "type": "short", "short_url": url, "real_url": real_url }) else: # url_type == "full" results.append({ "type": "full", "url": url }) return {"status": "success", "message": "链接转换成功", "results": results} @app.route('/api/convert', methods=['POST']) @require_api_key def api_convert(): """API端点,接收POST请求并转换链接""" if not request.is_json: return jsonify({"status": "error", "message": "请求必须是JSON格式"}), 400 data = request.get_json() if 'text' not in data: return jsonify({"status": "error", "message": "请求中必须包含'text'字段"}), 400 text = data['text'] result = convert_links(text) return jsonify(result) @app.route('/api/health', methods=['GET']) @require_api_key def health_check(): """健康检查端点""" return jsonify({"status": "ok", "message": "服务正常运行"}) @app.route('/', methods=['GET']) def home(): """主页,显示简单的使用说明""" return """
这是一个将小红书分享链接转换为真实可访问链接的API服务。
所有API请求都需要在请求头中包含有效的API密钥:
x-api-key: [您的API密钥]
API密钥可以通过环境变量 XHS_API_KEY
设置
端点: /api/convert
方法: POST
请求体:
{ "text": "包含小红书链接的文本" }
示例响应:
{ "status": "success", "message": "链接转换成功", "results": [ { "type": "short", "short_url": "http://xhslink.com/xxxx", "real_url": "https://www.xiaohongshu.com/discovery/item/..." } ] }
端点: /api/health
方法: GET
示例响应:
{ "status": "ok", "message": "服务正常运行" }""" if __name__ == '__main__': # 默认运行在7860端口,适配Hugging Face Spaces app.run(host='0.0.0.0', port=7860, debug=False, threaded=True)