| | |
| | | |
| | | def generate_xiaohongshu_article(film_name, locations): |
| | | """生成小红书风格的文章""" |
| | | prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的文章。要求: |
| | | try: |
| | | prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的文章。要求: |
| | | 1. 标题要吸引人,包含电影名称和拍摄地 |
| | | 2. 开头要吸引人,可以用电影中的经典台词或场景引入 |
| | | 3. 详细介绍每个拍摄地点的特色和亮点 |
| | |
| | | |
| | | 请以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 |
| | | completion = client.chat.completions.create( |
| | | model="bot-20250512103613-6rwj8", |
| | | messages=[ |
| | | {"role": "system", "content": "你是一个专业的小红书文案写手,擅长写吸引人的旅游攻略。"}, |
| | | {"role": "user", "content": prompt}, |
| | | ], |
| | | ) |
| | | |
| | | return completion.choices[0].message.content |
| | | except Exception as e: |
| | | print(f"生成小红书文章失败: {str(e)}") |
| | | return "" |
| | | |
| | | def generate_travel_route(film_name, locations): |
| | | """生成游玩路线""" |
| | | prompt = f"""请为电影《{film_name}》的拍摄地设计一条最优游玩路线。要求: |
| | | try: |
| | | prompt = f"""请为电影《{film_name}》的拍摄地设计一条最优游玩路线。要求: |
| | | 1. 考虑各个景点之间的距离和交通方式 |
| | | 2. 合理安排游览顺序,避免来回奔波 |
| | | 3. 预估每个景点的游览时间 |
| | |
| | | ] |
| | | }}""" |
| | | |
| | | 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) |
| | | 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 |
| | | except Exception as e: |
| | | print(f"解析路线失败: {str(e)}\n原始响应: {response_text}") |
| | | print(f"生成游玩路线失败: {str(e)}") |
| | | return None |
| | | |
| | | def generate_xiaohongshu_route(film_name, locations): |
| | | """生成小红书风格的路线攻略""" |
| | | prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的路线攻略。要求: |
| | | try: |
| | | prompt = f"""请为电影《{film_name}》的拍摄地写一篇小红书风格的路线攻略。要求: |
| | | 1. 标题要吸引人,突出"最佳路线"或"完美行程"等关键词 |
| | | 2. 开头要说明这条路线是如何规划的,为什么这样安排 |
| | | 3. 详细介绍每个景点的游览时间和交通方式 |
| | |
| | | |
| | | 请以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 |
| | | completion = client.chat.completions.create( |
| | | model="bot-20250512103613-6rwj8", |
| | | messages=[ |
| | | {"role": "system", "content": "你是一个专业的小红书文案写手,擅长写吸引人的旅游路线攻略。"}, |
| | | {"role": "user", "content": prompt}, |
| | | ], |
| | | ) |
| | | |
| | | return completion.choices[0].message.content |
| | | except Exception as e: |
| | | print(f"生成小红书路线攻略失败: {str(e)}") |
| | | return "" |
| | | |
| | | 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 [] |
| | | try: |
| | | 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", []) |
| | | else: |
| | | print(f"获取电影作品失败,状态码: {response.status_code}") |
| | | return [] |
| | | except Exception as e: |
| | | print(f"获取电影作品失败: {str(e)}") |
| | | return [] |
| | | |
| | | |
| | | def get_location_info_from_model(film_name): |
| | | """使用模型获取多个拍摄地点信息""" |
| | | prompt = f"""请为电影《{film_name}》生成所有主要拍摄地点的详细信息。每部电影通常有多个拍摄地点,请尽可能详细地列出所有重要的拍摄地点。 |
| | | try: |
| | | prompt = f"""请为电影《{film_name}》生成所有主要拍摄地点的详细信息。每部电影通常有多个拍摄地点,请尽可能详细地列出所有重要的拍摄地点。 |
| | | |
| | | 对于每个拍摄地点,请提供以下信息: |
| | | 1. 拍摄地点名称 |
| | |
| | | ] |
| | | |
| | | 请确保返回所有重要的拍摄地点,每个地点都要包含完整的信息。""" |
| | | # 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内容 |
| | | # 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 |
| | | # 解析 |
| | | location_info_list = json.loads(cleaned_text) |
| | | return location_info_list |
| | | except Exception as e: |
| | | print(f"解析失败: {str(e)}\n原始响应: {response_text}") |
| | | return None |
| | | except Exception as e: |
| | | print(f"获取拍摄地点信息失败: {str(e)}") |
| | | 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" |
| | | try: |
| | | 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 # 新增:小红书风格路线 |
| | | } |
| | | # 默认值设置 |
| | | 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 |
| | | # 更新默认值 |
| | | 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() |
| | | response = requests.post(url, json=default_data) |
| | | return response.json() |
| | | except Exception as e: |
| | | print(f"创建拍摄地点失败: {str(e)}") |
| | | return {"error": str(e)} |
| | | |
| | | 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) |
| | | try: |
| | | # 创建输出目录 |
| | | 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 if article else "文章生成失败") |
| | | |
| | | # 保存路线(JSON格式) |
| | | route_file = os.path.join(output_dir, f"{film_name}_route.json") |
| | | with open(route_file, "w", encoding="utf-8") as f: |
| | | if route: |
| | | json.dump(route, f, ensure_ascii=False, indent=2) |
| | | else: |
| | | json.dump({"error": "路线生成失败"}, 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 if route_article else "路线文章生成失败") |
| | | except Exception as e: |
| | | print(f"保存文件失败: {str(e)}") |
| | | |
| | | def main(): |
| | | # 获取所有电影作品 |
| | | film_works = get_film_works() |
| | | try: |
| | | film_works = get_film_works() |
| | | except Exception as e: |
| | | print(f"获取电影作品失败: {str(e)}") |
| | | return |
| | | |
| | | # 为每个电影作品创建拍摄地点 |
| | | for film in film_works: |
| | | film_name = film.get("nameCn") |
| | | film_id = film.get("id") |
| | | if film_name: |
| | | print(f"正在处理电影: {film_name}") |
| | | try: |
| | | 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) |
| | | # 获取所有拍摄地点信息 |
| | | 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}") |
| | | if article: |
| | | article = re.sub(r'```html|```', '', article) |
| | | print(f"\n生成的文章:\n{article}") |
| | | else: |
| | | print("文章生成失败,使用空内容") |
| | | |
| | | # 生成游玩路线(JSON格式) |
| | | route = generate_travel_route(film_name, location_info_list) |
| | | print(f"\n生成的路线:\n{json.dumps(route, ensure_ascii=False, indent=2)}") |
| | | if route: |
| | | print(f"\n生成的路线:\n{json.dumps(route, ensure_ascii=False, indent=2)}") |
| | | else: |
| | | print("路线生成失败,使用空内容") |
| | | |
| | | # 生成小红书风格路线 |
| | | 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}") |
| | | if route_article: |
| | | route_article = re.sub(r'```html|```', '', route_article) |
| | | print(f"\n生成的路线文章:\n{route_article}") |
| | | else: |
| | | print("路线文章生成失败,使用空内容") |
| | | |
| | | # 合并文章和路线 |
| | | 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()}") |
| | | try: |
| | | 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()}") |
| | | except Exception as e: |
| | | print(f"保存到新接口失败: {str(e)}") |
| | | |
| | | # 为每个拍摄地点创建记录 |
| | | 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}") |
| | | if location_info_list: |
| | | 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}") |
| | | else: |
| | | print("没有拍摄地点信息,跳过创建拍摄地点记录") |
| | | |
| | | # 保存文章和路线到文件 |
| | | save_article_and_route(film_id, film_name, article, route, route_article) |
| | | try: |
| | | save_article_and_route(film_id, film_name, article, route, route_article) |
| | | except Exception as e: |
| | | print(f"保存文件失败: {str(e)}") |
| | | else: |
| | | print(f"未能获取到电影 {film_name} 的拍摄地点信息") |
| | | print(f"电影名称为空,跳过处理") |
| | | except Exception as e: |
| | | print(f"处理电影 {film.get('nameCn', '未知电影')} 时发生错误: {str(e)}") |
| | | continue |
| | | |
| | | |
| | | if __name__ == "__main__": |