import os import requests import json from datetime import datetime from openai import OpenAI import re # 初始化 OpenAI 客户端 client = OpenAI( # 此为默认路径,您可根据业务所在地域进行配置 base_url="https://ark.cn-beijing.volces.com/api/v3/bots", # 从环境变量中获取您的 API Key api_key="5017c24f-581f-48fb-abef-8ac4654e9018", # 直接填写密钥 ) def generate_xiaohongshu_article(film_name, locations): """生成小红书风格的文章""" prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的文章。要求: 1. 标题要吸引人,包含电影名称和拍摄地 2. 开头要吸引人,可以用电影中的经典台词或场景引入 3. 详细介绍每个拍摄地点的特色和亮点 4. 包含实用的参观建议和交通信息 5. 使用emoji表情增加趣味性 6. 最后要有总结和推荐 7. 添加相关标签 请以html格式返回,包含标题、正文和标签.生成内容字体要符合在小程序上合适的大小阅读,标题不要超过h3。""" completion = client.chat.completions.create( model="bot-20250512103613-6rwj8", messages=[ {"role": "system", "content": "你是一个专业的小红书文案写手,擅长写吸引人的旅游攻略。"}, {"role": "user", "content": prompt}, ], ) return completion.choices[0].message.content def generate_travel_route(film_name, locations): """生成游玩路线""" 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=[ {"role": "system", "content": "你是一个专业的旅游路线规划师,擅长设计最优游览路线。"}, {"role": "user", "content": prompt}, ], ) try: response_text = completion.choices[0].message.content cleaned_text = re.sub(r'```json|```', '', response_text) cleaned_text = re.sub(r'^[^{[]*', '', cleaned_text) return json.loads(cleaned_text) except Exception as e: print(f"解析路线失败: {str(e)}\n原始响应: {response_text}") return None def generate_xiaohongshu_route(film_name, locations): """生成小红书风格的路线攻略""" prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的路线攻略。要求: 1. 标题要吸引人,突出"最佳路线"或"完美行程"等关键词 2. 开头要说明这条路线是如何规划的,为什么这样安排 3. 详细介绍每个景点的游览时间和交通方式 4. 使用emoji表情增加趣味性 5. 提供实用的时间安排建议 6. 包含备选路线方案 7. 最后要有总结和注意事项 8. 添加相关标签 请以html格式返回,包含标题、正文和标签,生成内容字体要符合在小程序上合适的大小阅读,标题不要超过h3。""" completion = client.chat.completions.create( model="bot-20250512103613-6rwj8", messages=[ {"role": "system", "content": "你是一个专业的小红书文案写手,擅长写吸引人的旅游路线攻略。"}, {"role": "user", "content": prompt}, ], ) return completion.choices[0].message.content def get_film_works(): url = "http://192.168.1.213:8090/flower/api/filmWorks/pending/create" response = requests.get(url) if response.status_code == 200: return response.json().get("data", []) return [] def get_location_info_from_model(film_name): """使用模型获取多个拍摄地点信息""" 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( model="bot-20250512103613-6rwj8", # bot-20250512103613-6rwj8 为您当前的智能体的ID,注意此处与Chat API存在差异。差异对比详见 SDK使用指南 # messages=[ # {"role": "system", "content": "你是DeepSeek,是一个 AI 人工智能助手"}, # {"role": "user", "content": "常见的十字花科植物有哪些?"}, # ], messages=[ {"role": "system", "content": "你是一个专业的影视拍摄地点信息专家,请根据电影名称生成所有重要拍摄地点的详细信息。"}, {"role": "user", "content": prompt}, ], ) print(completion.choices[0].message.content) if hasattr(completion, "references"): print(completion.references) if hasattr(completion.choices[0].message, "reasoning_content"): print(completion.choices[0].message.reasoning_content) # 对于R1模型,输出reasoning content # try: # # 尝试解析模型返回的JSON # response_text = completion.choices[0].message.content # location_info_list = json.loads(response_text) # return location_info_list # except: # # 如果解析失败,返回默认值 # return None try: response_text = completion.choices[0].message.content # 清理响应内容 cleaned_text = re.sub(r'```json|```', '', response_text) # 移除Markdown标记 cleaned_text = re.sub(r'^[^{[]*', '', cleaned_text) # 清理开头非JSON内容 # 解析 location_info_list = json.loads(cleaned_text) return location_info_list except Exception as e: print(f"解析失败: {str(e)}\n原始响应: {response_text}") return None def create_film_location(film_id, film_name, location_info, article, route_article): url = "http://192.168.1.213:8090/flower/api/filmLocation/new" # 默认值设置 default_data = { "filmId": film_id, "locationName": f"{film_name}拍摄地", "address": "待补充", "gpsLat": 0.0, "gpsLng": 0.0, "startDate": datetime.now().strftime("%Y-%m-%d"), "endDate": datetime.now().strftime("%Y-%m-%d"), "sceneType": "外景", "classicScene": "待补充", "isOpenVisit": 0, "visitInfo": json.dumps({"tips": "暂无参观信息"}), "landmarkDesc": "待补充", "transportGuide": "待补充", "parkingInfo": "待补充", "surroundingFacilities": "待补充", "arEntry": "", "status": 1, "deleted": 0, "createBy": "system", "updateBy": "system", "checkinCount": 0, "visitorPhotos": json.dumps([]), "xiaohongshuArticle": article, # 新增:小红书风格文章 "xiaohongshuRoute": route_article # 新增:小红书风格路线 } # 更新默认值 if location_info: for key, value in location_info.items(): if key in default_data: if key in ['visit_info', 'visitor_photos']: default_data[key] = json.dumps(value) else: default_data[key] = value response = requests.post(url, json=default_data) return response.json() def save_article_and_route(film_id, film_name, article, route, route_article): """保存文章和路线到文件""" # 创建输出目录 output_dir = "output" if not os.path.exists(output_dir): os.makedirs(output_dir) # 保存文章 article_file = os.path.join(output_dir, f"{film_name}_article.md") with open(article_file, "w", encoding="utf-8") as f: f.write(article) # 保存路线(JSON格式) route_file = os.path.join(output_dir, f"{film_name}_route.json") with open(route_file, "w", encoding="utf-8") as f: json.dump(route, f, ensure_ascii=False, indent=2) # 保存路线(小红书风格) route_article_file = os.path.join(output_dir, f"{film_name}_route_article.md") with open(route_article_file, "w", encoding="utf-8") as f: f.write(route_article) def main(): # 获取所有电影作品 film_works = get_film_works() # 为每个电影作品创建拍摄地点 for film in film_works: film_name = film.get("nameCn") film_id = film.get("id") if film_name: print(f"正在处理电影: {film_name}") # 获取所有拍摄地点信息 location_info_list = get_location_info_from_model(film_name) if location_info_list: # 生成小红书文章 article = generate_xiaohongshu_article(film_name, location_info_list) # 清理文章中的HTML标记 article = re.sub(r'```html|```', '', article) print(f"\n生成的文章:\n{article}") # 生成游玩路线(JSON格式) route = generate_travel_route(film_name, location_info_list) print(f"\n生成的路线:\n{json.dumps(route, ensure_ascii=False, indent=2)}") # 生成小红书风格路线 route_article = generate_xiaohongshu_route(film_name, location_info_list) # 清理路线文章中的HTML标记 route_article = re.sub(r'```html|```', '', route_article) print(f"\n生成的路线文章:\n{route_article}") # 合并文章和路线 combined_content = f"{article}\n\n{route_article}" # 保存到新接口 save_url = "http://192.168.1.213:8090/flower/api/filmWorks/edit" save_data = { "id": film_id, "type": "sys", "filmContent": combined_content } save_response = requests.post(save_url, json=save_data) print(f"保存到新接口结果: {save_response.json()}") # 为每个拍摄地点创建记录 for location_info in location_info_list: result = create_film_location(film_id, film_name, location_info, article, route_article) print(f"创建拍摄地点 {location_info.get('locationName', '未知地点')} 结果: {result}") # 保存文章和路线到文件 save_article_and_route(film_id, film_name, article, route, route_article) else: print(f"未能获取到电影 {film_name} 的拍摄地点信息") if __name__ == "__main__": main()