From 4992631aef19d7f644cbcd6cd5e37dde37c6e149 Mon Sep 17 00:00:00 2001
From: cloudroam <cloudroam>
Date: 星期一, 14 七月 2025 10:46:10 +0800
Subject: [PATCH] add:增加对外接口
---
app.py | 55 +++++++++
test2.py | 258 +++++++++++++++++++++++++++---------------
douban.py | 11 +
douban_tv.py | 2
4 files changed, 231 insertions(+), 95 deletions(-)
diff --git a/app.py b/app.py
index 872cff9..cb75612 100644
--- a/app.py
+++ b/app.py
@@ -10,6 +10,11 @@
from werkzeug.exceptions import BadRequest
from ner_config import NERConfig, RepaymentNERConfig, IncomeNERConfig, FlightNERConfig, TrainNERConfig
import re
+import threading
+import subprocess
+
+from test2 import process_films
+
# 配置日志
logging.basicConfig(
@@ -1681,5 +1686,55 @@
"message": "服务器内部错误"
}), 500
+
+def run_douban_spider(type_, tag):
+ subprocess.run(
+ ["python", "douban.py", type_, tag],
+ capture_output=True,
+ text=True
+ )
+
+def run_process_films():
+ try:
+ process_films()
+ except Exception as e:
+ logger.error(f"处理电影内容失败: {str(e)}")
+
+@app.route("/crawl-douban", methods=["POST"])
+def crawl_douban():
+ try:
+ default_params = {"type": "tv", "tag": "热门"}
+
+ # 尝试解析 JSON,失败则使用默认值
+ # 先检查 Content-Type 和数据结构
+ if request.is_json:
+ params = request.get_json()
+ if not isinstance(params, dict): # 确保是字典类型
+ params = default_params
+ else:
+ params = default_params
+
+ # 获取参数(带默认值)
+ type_ = params.get("type", default_params["type"])
+ tag = params.get("tag", default_params["tag"])
+ # 打印接收到的参数(调试用)
+ print(f"Received params - type: {type_}, tag: {tag}")
+
+ # 启动线程异步执行爬虫
+ t = threading.Thread(target=run_douban_spider, args=(type_, tag))
+ t.start()
+
+ return jsonify({"status": "success", "message": "爬虫任务已启动", "type": type_, "tag": tag})
+ except Exception as e:
+ return jsonify({"status": "error", "message": str(e)}), 500
+
+@app.route('/generate-film-content', methods=['POST'])
+def generate_film_content_api():
+ """生成电影内容接口"""
+ try:
+ threading.Thread(target=run_process_films).start()
+ return jsonify({"status": "accepted", "message": "任务已异步启动"})
+ except Exception as e:
+ return jsonify({"status": "error", "message": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
\ No newline at end of file
diff --git a/douban.py b/douban.py
index 3608f81..9b00899 100644
--- a/douban.py
+++ b/douban.py
@@ -1,7 +1,16 @@
from douban_tv import DoubanTVSpider
from scrapy.crawler import CrawlerProcess
+import sys
if __name__ == "__main__":
+ # 获取命令行参数
+ type_ = "tv"
+ tag = "热门"
+ if len(sys.argv) > 1:
+ type_ = sys.argv[1]
+ if len(sys.argv) > 2:
+ tag = sys.argv[2]
+
process = CrawlerProcess(settings={
"USER_AGENT": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/112.0.0.0 Safari/537.36",
"DOWNLOAD_DELAY": 2,
@@ -9,5 +18,5 @@
"ROBOTSTXT_OBEY": False,
"LOG_LEVEL": "INFO"
})
- process.crawl(DoubanTVSpider)
+ process.crawl(DoubanTVSpider, type_=type_, tag=tag)
process.start()
\ No newline at end of file
diff --git a/douban_tv.py b/douban_tv.py
index d3a8796..c37ff96 100644
--- a/douban_tv.py
+++ b/douban_tv.py
@@ -127,7 +127,7 @@
# 发送数据到API
try:
response = requests.post(
- 'http://192.168.1.213:8080/flower/api/filmWorks/new',
+ 'http://14.103.144.28:8090/flower/api/filmWorks/new',
json=api_data,
headers={'Content-Type': 'application/json'}
)
diff --git a/test2.py b/test2.py
index d8105ab..1f521bd 100644
--- a/test2.py
+++ b/test2.py
@@ -14,21 +14,164 @@
api_key="5017c24f-581f-48fb-abef-8ac4654e9018", # 直接填写密钥
)
+DEFAULT_PROMPTS = {
+ "promptArticle": """请为电影《{film_name}》的拍摄地写一篇小红书风格的文章要求:
+ 1. 标题要吸引人,包含电影名称和拍摄地
+ 2. 开头要吸引人,可以用电影中的经典台词或场景引入
+ 3. 详细介绍每个拍摄地点的特色和亮点
+ 4. 包含实用的参观建议和交通信息
+ 5. 使用emoji表情增加趣味性
+ 6. 最后要有总结和推荐
+ 7. 添加相关标签
+ 请以html格式返回,包含标题、正文和标签.生成内容字体要符合在小程序上合适的大小阅读,标题不要超过h3。""",
+ "promptRoute": """请为电影《{film_name}》的拍摄地设计一条最优游玩路线。要求:
+ 1. 考虑各个景点之间的距离和交通方式
+ 2. 合理安排游览顺序,避免来回奔波
+ 3. 预估每个景点的游览时间
+ 4. 提供具体的交通建议
+ 5. 考虑用餐和休息时间
+ 6. 提供备选方案
+
+ 请以JSON格式返回,格式如下:
+ {{
+ "route_name": "路线名称",
+ "total_time": "预计总时间",
+ "stops": [
+ {{
+ "location_name": "地点名称",
+ "visit_time": "建议游览时间",
+ "transportation": "前往下一个地点的交通方式",
+ "tips": "游览建议"
+ }}
+ ],
+ "alternative_routes": [
+ {{
+ "route_name": "备选路线名称",
+ "description": "路线说明"
+ }}
+ ]
+ }}""",
+ "promptTravel": """请为电影《{film_name}》的拍摄地写一篇小红书风格的路线攻略要求:
+ 1. 标题要吸引人,突出"最佳路线"或"完美行程"等关键词
+ 2. 开头要说明这条路线是如何规划的,为什么这样安排
+ 3. 详细介绍每个景点的游览时间和交通方式
+ 4. 使用emoji表情增加趣味性
+ 5. 提供实用的时间安排建议
+ 6. 包含备选路线方案
+ 7. 最后要有总结和注意事项
+ 8. 添加相关标签
+
+ 请以html格式返回,包含标题、正文和标签,生成内容字体要符合在小程序上合适的大小阅读,标题不要超过h3。""",
+ "promptLocation": """请为电影《{film_name}》生成所有主要拍摄地点细信息。每部电影通常有多个拍摄地点,请尽可能详细地列出所有重要的拍摄地点。
+ 对于每个拍摄地点,请提供以下信息:
+ 1. 拍摄地点名称
+ 2. 详细地址
+ 3. 场景类型
+ 4. 经典画面描述
+ 5. 是否开放参观
+ 6. 参观提示
+ 7. 地标性建筑描述
+ 8. 交通指引说明
+ 9. 停车场信息
+ 10. 周边设施描述
+
+ 请以JSON数组格式返回,格式如下:
+ [
+ {{
+ "locationName": "地点1名称",
+ "address": "地点1详细地址",
+ "gpsLat": "纬度坐标(精确到小数点后6位)",
+ "gpsLng": "经度坐标(精确到小数点后6位)",
+ "sceneType": "场景类型",
+ "classicScene": "经典画面描述",
+ "isOpenVisit": 0或1,
+ "visitInfo": "参观提示",
+ "landmarkDesc": "地标描述",
+ "transportGuide": "交通指引",
+ "parkingInfo": "停车信息",
+ "surroundingFacilities": "周边设施"
+ }},
+ {{
+ "locationName": "地点2名称",
+ ...
+ }}
+ ]
+
+ 请确保返回所有重要的拍摄地点,每个地点都要包含完整的信息。"""
+}
+
+
+def get_ai_task_config():
+ """从API获取AI任务配置,保留原始HTML内容"""
+ try:
+ # 设置请求超时时间
+ response = requests.get(
+ "http://14.103.144.28:8090/flower/api/aiTaskConfig/all",
+ timeout=100
+ )
+
+ # 检查HTTP状态码
+ response.raise_for_status()
+
+ # 解析JSON响应
+ response_data = response.json()
+
+ # 验证响应结构
+ if response_data.get("code") != "0" or not isinstance(response_data.get("data"), list):
+ print(f"无效的API响应结构: {response_data}")
+ return {}
+
+ config_list = response_data["data"]
+
+ # 返回第一条有效配置(保留原始HTML内容)
+ if config_list:
+ return {
+ "promptArticle": config_list[0].get("promptArticle", ""),
+ "promptRoute": config_list[0].get("promptRoute", ""),
+ "promptTravel": config_list[0].get("promptTravel", ""),
+ "promptLocation": config_list[0].get("promptLocation", "") # 注意字段名拼写差异
+ }
+ return {}
+
+ except requests.exceptions.RequestException as e:
+ print(f"请求AI任务配置失败: {str(e)}")
+ return {}
+ except json.JSONDecodeError as e:
+ print(f"解析API响应JSON失败: {str(e)}")
+ return {}
+ except Exception as e:
+ print(f"获取AI任务配置发生未知错误: {str(e)}")
+ return {}
+
+def get_prompt(prompt_type):
+ """获取指定类型的提示模板
+ 参数:
+ prompt_type: 提示类型,必须是DEFAULT_PROMPTS中定义的键
+
+ 返回:
+ 从API获取的提示模板,如果为空则返回默认模板
+ """
+ # 验证输入参数
+ if prompt_type not in DEFAULT_PROMPTS:
+ raise ValueError(f"无效的prompt类型: {prompt_type}")
+
+ # 获取配置
+ config = get_ai_task_config()
+
+ # 获取指定类型的提示,确保内容非空
+# custom_prompt = config.get(prompt_type, "").strip()
+ custom_prompt = config.get(prompt_type)
+
+ # 更严格的空值检查
+ if custom_prompt is not None and str(custom_prompt).strip():
+ return str(custom_prompt).strip()
+ # 返回有效的提示模板
+ return custom_prompt if custom_prompt else DEFAULT_PROMPTS[prompt_type]
def generate_xiaohongshu_article(film_name, locations):
"""生成小红书风格的文章"""
+ prompt = get_prompt("promptArticle").format(film_name=film_name)
try:
- prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的文章。要求:
-1. 标题要吸引人,包含电影名称和拍摄地
-2. 开头要吸引人,可以用电影中的经典台词或场景引入
-3. 详细介绍每个拍摄地点的特色和亮点
-4. 包含实用的参观建议和交通信息
-5. 使用emoji表情增加趣味性
-6. 最后要有总结和推荐
-7. 添加相关标签
-
-请以html格式返回,包含标题、正文和标签.生成内容字体要符合在小程序上合适的大小阅读,标题不要超过h3。"""
-
completion = client.chat.completions.create(
model="bot-20250512103613-6rwj8",
messages=[
@@ -44,35 +187,8 @@
def generate_travel_route(film_name, locations):
"""生成游玩路线"""
+ prompt = get_prompt("promptRoute").format(film_name=film_name)
try:
- prompt = f"""请为电影《{film_name}》的拍摄地设计一条最优游玩路线。要求:
-1. 考虑各个景点之间的距离和交通方式
-2. 合理安排游览顺序,避免来回奔波
-3. 预估每个景点的游览时间
-4. 提供具体的交通建议
-5. 考虑用餐和休息时间
-6. 提供备选方案
-
-请以JSON格式返回,格式如下:
-{{
- "route_name": "路线名称",
- "total_time": "预计总时间",
- "stops": [
- {{
- "location_name": "地点名称",
- "visit_time": "建议游览时间",
- "transportation": "前往下一个地点的交通方式",
- "tips": "游览建议"
- }}
- ],
- "alternative_routes": [
- {{
- "route_name": "备选路线名称",
- "description": "路线说明"
- }}
- ]
-}}"""
-
completion = client.chat.completions.create(
model="bot-20250512103613-6rwj8",
messages=[
@@ -95,18 +211,8 @@
def generate_xiaohongshu_route(film_name, locations):
"""生成小红书风格的路线攻略"""
+ prompt = get_prompt("promptTravel").format(film_name=film_name)
try:
- prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的路线攻略。要求:
-1. 标题要吸引人,突出"最佳路线"或"完美行程"等关键词
-2. 开头要说明这条路线是如何规划的,为什么这样安排
-3. 详细介绍每个景点的游览时间和交通方式
-4. 使用emoji表情增加趣味性
-5. 提供实用的时间安排建议
-6. 包含备选路线方案
-7. 最后要有总结和注意事项
-8. 添加相关标签
-
-请以html格式返回,包含标题、正文和标签,生成内容字体要符合在小程序上合适的大小阅读,标题不要超过h3。"""
completion = client.chat.completions.create(
model="bot-20250512103613-6rwj8",
@@ -123,7 +229,7 @@
def get_film_works():
try:
- url = "http://192.168.1.213:8090/flower/api/filmWorks/pending/create"
+ url = "http://14.103.144.28:8090/flower/api/filmWorks/pending/create"
response = requests.get(url)
if response.status_code == 200:
return response.json().get("data", [])
@@ -137,44 +243,8 @@
def get_location_info_from_model(film_name):
"""使用模型获取多个拍摄地点信息"""
+ prompt = get_prompt("promptLocation").format(film_name=film_name)
try:
- prompt = f"""请为电影《{film_name}》生成所有主要拍摄地点的详细信息。每部电影通常有多个拍摄地点,请尽可能详细地列出所有重要的拍摄地点。
-
-对于每个拍摄地点,请提供以下信息:
-1. 拍摄地点名称
-2. 详细地址
-3. 场景类型
-4. 经典画面描述
-5. 是否开放参观
-6. 参观提示
-7. 地标性建筑描述
-8. 交通指引说明
-9. 停车场信息
-10. 周边设施描述
-
-请以JSON数组格式返回,格式如下:
-[
- {{
- "locationName": "地点1名称",
- "address": "地点1详细地址",
- "gpsLat": "纬度坐标(精确到小数点后6位)",
- "gpsLng": "经度坐标(精确到小数点后6位)",
- "sceneType": "场景类型",
- "classicScene": "经典画面描述",
- "isOpenVisit": 0或1,
- "visitInfo": "参观提示",
- "landmarkDesc": "地标描述",
- "transportGuide": "交通指引",
- "parkingInfo": "停车信息",
- "surroundingFacilities": "周边设施"
- }},
- {{
- "locationName": "地点2名称",
- ...
- }}
-]
-
-请确保返回所有重要的拍摄地点,每个地点都要包含完整的信息。"""
# Non-streaming:
print("----- standard request -----")
completion = client.chat.completions.create(
@@ -221,7 +291,7 @@
def create_film_location(film_id, film_name, location_info, article, route_article):
try:
- url = "http://192.168.1.213:8090/flower/api/filmLocation/new"
+ url = "http://14.103.144.28:8090/flower/api/filmLocation/new"
# 默认值设置
default_data = {
@@ -294,7 +364,7 @@
except Exception as e:
print(f"保存文件失败: {str(e)}")
-def main():
+def process_films():
# 获取所有电影作品
try:
film_works = get_film_works()
@@ -343,7 +413,7 @@
# 保存到新接口
try:
- save_url = "http://192.168.1.213:8090/flower/api/filmWorks/edit"
+ save_url = "http://14.103.144.28:8090/flower/api/filmWorks/edit"
save_data = {
"id": film_id,
"type": "sys",
@@ -373,6 +443,8 @@
print(f"处理电影 {film.get('nameCn', '未知电影')} 时发生错误: {str(e)}")
continue
+def main():
+ process_films()
-if __name__ == "__main__":
- main()
\ No newline at end of file
+# if __name__ == "__main__":
+# main()
\ No newline at end of file
--
Gitblit v1.9.3