对比新文件 |
| | |
| | | from douban_tv import DoubanTVSpider |
| | | from scrapy.crawler import CrawlerProcess |
| | | |
| | | if __name__ == "__main__": |
| | | 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, |
| | | "CONCURRENT_REQUESTS": 1, |
| | | "ROBOTSTXT_OBEY": False, |
| | | "LOG_LEVEL": "INFO" |
| | | }) |
| | | process.crawl(DoubanTVSpider) |
| | | process.start() |
对比新文件 |
| | |
| | | # import scrapy |
| | | # import json |
| | | # import requests |
| | | # from datetime import datetime |
| | | # from urllib.parse import urljoin |
| | | # |
| | | # |
| | | # class DoubanTVSpider(scrapy.Spider): |
| | | # name = 'douban_tv' |
| | | # allowed_domains = ['movie.douban.com'] |
| | | # |
| | | # # 使用start()替代已弃用的start_requests() |
| | | # def start_requests(self): |
| | | # headers = { |
| | | # 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/112.0.0.0 Safari/537.36' |
| | | # } |
| | | # # 同时爬取电影和电视剧 |
| | | # urls = [ |
| | | # "https://movie.douban.com/j/new_search_subjects?sort=U&tag=电视剧&start=0", |
| | | # "https://movie.douban.com/j/new_search_subjects?sort=U&tag=电影&start=0" |
| | | # ] |
| | | # |
| | | # for url in urls: |
| | | # yield scrapy.Request(url, headers=headers, callback=self.parse) |
| | | # |
| | | # def parse(self, response): |
| | | # try: |
| | | # data = json.loads(response.text) |
| | | # except json.JSONDecodeError: |
| | | # self.logger.error("JSON解析失败: %s", response.url) |
| | | # return |
| | | # |
| | | # for item in data.get('data', []): |
| | | # detail_url = item.get('url') |
| | | # if detail_url: |
| | | # yield scrapy.Request( |
| | | # detail_url, |
| | | # callback=self.parse_detail, |
| | | # meta={'item': item} |
| | | # ) |
| | | # |
| | | # # 分页逻辑 |
| | | # current_start = int(response.url.split('start=')[-1]) |
| | | # next_start = current_start + 20 |
| | | # if next_start < 60: |
| | | # next_url = response.url.replace(f'start={current_start}', f'start={next_start}') |
| | | # yield response.follow(next_url, callback=self.parse) |
| | | # |
| | | # def parse_detail(self, response): |
| | | # item = response.meta['item'] |
| | | # |
| | | # # 获取详细信息 |
| | | # title = item.get('title', '').strip() |
| | | # rate = item.get('rate', '') |
| | | # year = item.get('date', '')[:4] if item.get('date') else '' |
| | | # |
| | | # # 从详情页获取更多信息 |
| | | # info = response.css('#info').get('') |
| | | # |
| | | # # 获取导演 |
| | | # director = ','.join(response.css('#info .attrs a::text').getall()[:1]) |
| | | # |
| | | # # 获取演员 |
| | | # actors = ','.join(response.css('#info .actor .attrs a::text').getall()) |
| | | # |
| | | # # 获取类型 |
| | | # type_text = ','.join(response.css('#info span[property="v:genre"]::text').getall()) |
| | | # |
| | | # # 获取制片方 |
| | | # producer = response.css('#info span:contains("制片国家/地区:") + ::text').get('').strip() |
| | | # |
| | | # # 获取剧情简介 |
| | | # synopsis = response.css('#link-report span[property="v:summary"]::text').get('').strip() |
| | | # |
| | | # # 获取封面图片 |
| | | # cover_url = response.css('#mainpic img::attr(src)').get('') |
| | | # cover_alt = response.css('#mainpic img::attr(alt)').get('') |
| | | # |
| | | # # 构建API请求数据 |
| | | # api_data = { |
| | | # 'nameCn': title, |
| | | # 'nameEn': '', # 豆瓣API没有提供英文名 |
| | | # 'type': '电视剧' if '电视剧' in response.url else '电影', |
| | | # 'releaseYear': f"{year}-01-01T00:00:00" if year else None, |
| | | # 'director': director, |
| | | # 'producer': producer, |
| | | # 'actors': actors, |
| | | # 'keywords': type_text, |
| | | # 'synopsis': synopsis, |
| | | # 'coverUrl': cover_url, |
| | | # 'coverAlt': cover_alt |
| | | # } |
| | | # |
| | | # # 发送数据到API |
| | | # try: |
| | | # response = requests.post( |
| | | # 'http://192.168.1.213:8080/flower/api/filmWorks/new', |
| | | # json=api_data, |
| | | # headers={'Content-Type': 'application/json'} |
| | | # ) |
| | | # if response.status_code == 200: |
| | | # self.logger.info(f"成功保存作品: {title}") |
| | | # else: |
| | | # self.logger.error(f"保存失败: {title}, 状态码: {response.status_code}") |
| | | # except Exception as e: |
| | | # self.logger.error(f"API请求失败: {str(e)}") |
| | | # |
| | | # # 添加设置(可选) |
| | | # custom_settings = { |
| | | # 'DOWNLOAD_DELAY': 2, # 增加延迟,避免被封 |
| | | # 'CONCURRENT_REQUESTS': 1, # 限制并发请求 |
| | | # 'ROBOTSTXT_OBEY': False |
| | | # } |
对比新文件 |
| | |
| | | import scrapy |
| | | import json |
| | | import requests |
| | | from datetime import datetime |
| | | from urllib.parse import urljoin |
| | | |
| | | |
| | | class DoubanTVSpider(scrapy.Spider): |
| | | name = 'douban_tv' |
| | | allowed_domains = ['movie.douban.com'] |
| | | |
| | | # 使用start()替代已弃用的start_requests() |
| | | def start_requests(self): |
| | | headers = { |
| | | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/112.0.0.0 Safari/537.36', |
| | | 'Referer': 'https://movie.douban.com/tv/' |
| | | } |
| | | # 同时爬取电影和电视剧 |
| | | # urls = [ |
| | | # "https://movie.douban.com/j/new_search_subjects?sort=U&tag=电视剧&start=0", |
| | | # "https://movie.douban.com/j/new_search_subjects?sort=U&tag=电影&start=0" |
| | | # ] |
| | | # 路径2最新电视剧 |
| | | urls = [ |
| | | "https://movie.douban.com/j/search_subjects?type=tv&tag=%E7%83%AD%E9%97%A8&sort=recommend&start=0" |
| | | ] |
| | | for url in urls: |
| | | yield scrapy.Request(url, headers=headers, callback=self.parse) |
| | | |
| | | def parse(self, response): |
| | | try: |
| | | data = json.loads(response.text) |
| | | self.logger.info(f"解析到的数据: {data}") # 添加日志 |
| | | except json.JSONDecodeError: |
| | | self.logger.error("JSON解析失败: %s", response.url) |
| | | return |
| | | |
| | | # 检查数据结构 |
| | | items = data.get('subjects', []) # 新API使用subjects字段 |
| | | if not items: |
| | | self.logger.error("未找到subjects数据") |
| | | return |
| | | |
| | | for item in items: |
| | | detail_url = item.get('url') |
| | | if detail_url: |
| | | yield scrapy.Request( |
| | | detail_url, |
| | | callback=self.parse_detail, |
| | | meta={'item': item} |
| | | ) |
| | | |
| | | # 分页逻辑 |
| | | current_start = int(response.url.split('start=')[-1]) |
| | | next_start = current_start + 20 |
| | | if next_start < 60: |
| | | next_url = response.url.replace(f'start={current_start}', f'start={next_start}') |
| | | yield response.follow(next_url, callback=self.parse) |
| | | |
| | | def parse_detail(self, response): |
| | | item = response.meta['item'] |
| | | |
| | | # 从 JSON 中提取了 url 字段(格式: https://movie.douban.com/subject/25754848/),用于后续请求。 |
| | | |
| | | # 获取详细信息 |
| | | title = item.get('title', '').strip() |
| | | rate = item.get('rate', '') |
| | | year = item.get('date', '')[:4] if item.get('date') else '' |
| | | |
| | | # 从详情页获取更多信息 |
| | | info = response.css('#info').get('') |
| | | |
| | | # 获取导演 |
| | | directors = response.css('#info span:contains("导演") + .attrs a::text').getall() |
| | | director = ','.join(directors) |
| | | |
| | | # 获取演员 |
| | | # 使用相邻兄弟选择器定位 |
| | | actor = response.css('#info span:contains("主演") + .attrs a::text').getall() |
| | | actors = ','.join(actor) |
| | | |
| | | # 获取类型 |
| | | type_text = ','.join(response.css('#info span[property="v:genre"]::text').getall()) |
| | | |
| | | # 获取制片方 |
| | | producer = response.xpath('//span[contains(text(), "制片国家/地区")]/following::text()[1]').get().strip() |
| | | |
| | | # 获取剧情简介 |
| | | # 同时提取可见和隐藏内容 |
| | | # 提取简介(最终方案) |
| | | synopsises = response.xpath('//span[@property="v:summary"]//text()').getall() |
| | | synopsis = ' '.join(''.join(synopsises).strip().split()) |
| | | |
| | | # 提取首播年份 |
| | | # release_date = response.css('span[property="v:initialReleaseDate"]::text').get() |
| | | # year = release_date.split('-')[0] if release_date else "未知" |
| | | |
| | | # 提取年份(最优方案) |
| | | year= response.css('.year::text').re_first(r'(\d+)') # 直接匹配数字 |
| | | |
| | | # 如果正则失效的备选方案 |
| | | if not year: |
| | | year_text = response.css('.year::text').get() |
| | | year = year_text.strip('()') if year_text else "未知" |
| | | |
| | | # 获取封面图片 |
| | | cover_url = response.css('#mainpic img::attr(src)').get('') |
| | | cover_alt = response.css('#mainpic img::attr(alt)').get('') |
| | | |
| | | # 构建API请求数据 |
| | | api_data = { |
| | | 'nameCn': title, |
| | | 'nameEn': '', # 豆瓣API没有提供英文名 |
| | | 'type': 'tv', |
| | | 'releaseYear': year, |
| | | 'director': director, |
| | | 'producer': producer, |
| | | 'actors': actors, |
| | | 'keywords': type_text, |
| | | 'synopsis': synopsis, |
| | | 'coverUrl': cover_url, |
| | | 'coverAlt': cover_alt, |
| | | 'userType': 'official' |
| | | |
| | | } |
| | | |
| | | # 发送数据到API |
| | | try: |
| | | response = requests.post( |
| | | 'http://192.168.1.213:8080/flower/api/filmWorks/new', |
| | | json=api_data, |
| | | headers={'Content-Type': 'application/json'} |
| | | ) |
| | | if response.status_code == 200: |
| | | self.logger.info(f"成功保存作品: {title}") |
| | | else: |
| | | self.logger.error(f"保存失败: {title}, 状态码: {response.status_code}") |
| | | except Exception as e: |
| | | self.logger.error(f"API请求失败: {str(e)}") |
| | | |
| | | # 添加设置(可选) |
| | | custom_settings = { |
| | | 'DOWNLOAD_DELAY': 2, # 增加延迟,避免被封 |
| | | 'CONCURRENT_REQUESTS': 1, # 限制并发请求 |
| | | 'ROBOTSTXT_OBEY': False, |
| | | 'LOG_LEVEL': 'DEBUG' # 设置日志级别为DEBUG以查看更多信息 |
| | | } |
对比新文件 |
| | |
| | | # import requests |
| | | # import json |
| | | # |
| | | # |
| | | # def deepseek_generation(prompt, api_key): |
| | | # """ |
| | | # 调用DeepSeek模型的生成接口 |
| | | # 参数: |
| | | # prompt: 用户输入的提示文本 |
| | | # api_key: 用户的API密钥 |
| | | # 返回: |
| | | # str: 模型生成的文本 |
| | | # """ |
| | | # url = "https://api.deepseek.com/v1/chat/completions" |
| | | # |
| | | # headers = { |
| | | # "Content-Type": "application/json", |
| | | # "Authorization": f"Bearer {api_key}", |
| | | # "Accept": "application/json" |
| | | # } |
| | | # |
| | | # # payload = { |
| | | # # "model": "deepseek-reasoner", |
| | | # # "messages": [ |
| | | # # {"role": "user", "content": prompt} |
| | | # # ], |
| | | # # "temperature": 0.3, |
| | | # # "max_tokens": 2048 |
| | | # # } |
| | | # payload = { |
| | | # "model": "deepseek-chat", # 确认模型名称 |
| | | # "messages": [ |
| | | # {"role": "system", "content": "你是一个有帮助的助手"}, |
| | | # {"role": "user", "content": prompt} |
| | | # ], |
| | | # "temperature": 0.7, # 调整为官网默认值 |
| | | # "max_tokens": 2048, |
| | | # "top_p": 1, |
| | | # "frequency_penalty": 0 |
| | | # } |
| | | # try: |
| | | # response = requests.post(url, headers=headers, data=json.dumps(payload)) |
| | | # response.raise_for_status() |
| | | # |
| | | # result = response.json() |
| | | # return result['choices'][0]['message']['content'] |
| | | # except requests.exceptions.RequestException as e: |
| | | # print(f"API请求错误: {e}") |
| | | # return None |
| | | # except KeyError: |
| | | # print("响应格式解析失败") |
| | | # return None |
| | | # |
| | | # |
| | | # if __name__ == "__main__": |
| | | # # 使用示例 |
| | | # api_key = "sk-055784b1d4904ce6a34b5733a091c130" # 替换为你的实际API密钥 |
| | | # user_input = input("请输入您的问题:") |
| | | # |
| | | # response = deepseek_generation(user_input, api_key) |
| | | # |
| | | # if response: |
| | | # print("\nDeepSeek回答:") |
| | | # print(response) |
| | | # else: |
| | | # print("生成内容时出现错误") |
| | | |
| | | |
| | | import os |
| | | from openai import OpenAI |
| | | |
| | | client = OpenAI( |
| | | api_key = os.environ.get("5017c24f-581f-48fb-abef-8ac4654e9018"), |
| | | base_url = "https://ark.cn-beijing.volces.com/api/v3", |
| | | ) |
| | | |
| | | # Non-streaming: |
| | | print("----- standard request -----") |
| | | completion = client.chat.completions.create( |
| | | model = "deepseek-r1-250120", # your model endpoint ID |
| | | messages = [ |
| | | {"role": "system", "content": "你是人工智能助手"}, |
| | | {"role": "user", "content": "帮我生成无忧渡电视剧中的实景拍摄地和行程安排?"}, |
| | | ], |
| | | ) |
| | | print(completion.choices[0].message.content) |
| | | |
| | | # Streaming: |
| | | print("----- streaming request -----") |
| | | stream = client.chat.completions.create( |
| | | model = "deepseek-r1-250120", # your model endpoint ID |
| | | messages = [ |
| | | {"role": "system", "content": "你是人工智能助手"}, |
| | | {"role": "user", "content": "帮我生成无忧渡电视剧中的实景拍摄地和行程安排?"}, |
| | | ], |
| | | stream=True |
| | | ) |
| | | |
| | | for chunk in stream: |
| | | if not chunk.choices: |
| | | continue |
| | | print(chunk.choices[0].delta.content, end="") |
| | | print() |
对比新文件 |
| | |
| | | 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/all" |
| | | 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") # 新增:获取电影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) |
| | | 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) |
| | | print(f"\n生成的路线文章:\n{route_article}") |
| | | |
| | | # 为每个拍摄地点创建记录 |
| | | 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() |
对比新文件 |
| | |
| | | import os |
| | | from openai import OpenAI |
| | | |
| | | # 请确保您已将 API Key 存储在环境变量 ARK_API_KEY 中 |
| | | # 初始化Openai客户端,从环境变量中读取您的API Key |
| | | client = OpenAI( |
| | | # 此为默认路径,您可根据业务所在地域进行配置 |
| | | base_url="https://ark.cn-beijing.volces.com/api/v3/bots", |
| | | # 从环境变量中获取您的 API Key |
| | | api_key="5017c24f-581f-48fb-abef-8ac4654e9018", # 直接填写密钥 |
| | | ) |
| | | |
| | | # 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": "常见的十字花科植物有哪些?"}, |
| | | ], |
| | | ) |
| | | 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 |
| | | |
| | | |
| | | # # Streaming: |
| | | # print("----- streaming request -----") |
| | | # stream = client.chat.completions.create( |
| | | # model="bot-20250512103613-6rwj8", # bot-20250512103613-6rwj8 为您当前的智能体的ID,注意此处与Chat API存在差异。差异对比详见 SDK使用指南 |
| | | # messages=[ |
| | | # {"role": "system", "content": "你是DeepSeek,是一个 AI 人工智能助手"}, |
| | | # {"role": "user", "content": "常见的十字花科植物有哪些?"}, |
| | | # ], |
| | | # stream=True, |
| | | # ) |
| | | # for chunk in stream: |
| | | # if hasattr(chunk, "references"): |
| | | # print(chunk.references) |
| | | # if not chunk.choices: |
| | | # continue |
| | | # if chunk.choices[0].delta.content: |
| | | # print(chunk.choices[0].delta.content, end="") |
| | | # elif hasattr(chunk.choices[0].delta, "reasoning_content"): |
| | | # print(chunk.choices[0].delta.reasoning_content) |
| | | print() |