File size: 5,284 Bytes
f447a3f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
from flask import Flask, request, jsonify
import re
import requests
app = Flask(__name__)
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'])
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'])
def health_check():
"""健康检查端点"""
return jsonify({"status": "ok", "message": "服务正常运行"})
@app.route('/', methods=['GET'])
def home():
"""主页,显示简单的使用说明"""
return """
<html>
<head>
<title>小红书链接转换API</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; line-height: 1.6; }
h1 { color: #D81E06; }
code { background: #f4f4f4; padding: 2px 5px; border-radius: 3px; }
pre { background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; }
</style>
</head>
<body>
<h1>小红书链接转换API</h1>
<p>这是一个将小红书分享链接转换为真实可访问链接的API服务。</p>
<h2>API使用说明</h2>
<h3>转换链接</h3>
<p><strong>端点:</strong> <code>/api/convert</code></p>
<p><strong>方法:</strong> POST</p>
<p><strong>请求体:</strong></p>
<pre>
{
"text": "包含小红书链接的文本"
}
</pre>
<p><strong>示例响应:</strong></p>
<pre>
{
"status": "success",
"message": "链接转换成功",
"results": [
{
"type": "short",
"short_url": "http://xhslink.com/xxxx",
"real_url": "https://www.xiaohongshu.com/discovery/item/..."
}
]
}
</pre>
<h3>健康检查</h3>
<p><strong>端点:</strong> <code>/api/health</code></p>
<p><strong>方法:</strong> GET</p>
<p><strong>示例响应:</strong></p>
<pre>
{
"status": "ok",
"message": "服务正常运行"
}
</pre>
</body>
</html>
"""
if __name__ == '__main__':
# 默认运行在7860端口,适配Hugging Face Spaces
app.run(host='0.0.0.0', port=7860, debug=False) |