beijing-exhibitions/logs/cron.log
... ...
@@ -5901,3 +5901,51 @@ openclaw feishu_doc write --doc_token IIpVd0zDZoJgSSxPdsXc0DzHneh --title '北
5901 5901
[2026-07-13 09:00:02] ✓ 今日记忆已更新(成功)
5902 5902
[2026-07-13 09:00:02] ========== 任务执行成功 ==========
5903 5903
✅ 北京展览爬取成功 (2026-07-13) - 共 20 个展览
5904
+[2026-07-14 09:00:02] ========== 开始执行展览爬取任务 ==========
5905
+[2026-07-14 09:00:02] [INFO] ============================================================
5906
+[2026-07-14 09:00:02] [INFO] 北京展览爬取(优先北京市文物局)
5907
+[2026-07-14 09:00:02] [INFO] ============================================================
5908
+[2026-07-14 09:00:02] [INFO] 数据库初始化完成
5909
+[2026-07-14 09:00:02] [INFO]
5910
+【1】北京市文物局 ⭐⭐⭐⭐⭐
5911
+[2026-07-14 09:00:04] [INFO] 获取 2 个
5912
+[2026-07-14 09:00:04] [INFO]
5913
+【2】各大博物馆 ⭐⭐⭐⭐
5914
+[2026-07-14 09:00:14] [INFO]
5915
+【3】聚合信息 ⭐⭐⭐
5916
+[2026-07-14 09:00:16] [INFO] 去重后:20 个
5917
+[2026-07-14 09:00:16] [INFO] 对比:新增18个,移除3个
5918
+{"status": "success", "total": 20, "comparison": {"is_same": false, "new_count": 18, "removed_count": 3, "message": "新增18个,移除3个"}, "report": "/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md"}
5919
+[2026-07-14 09:00:16] [INFO] ============================================================
5920
+[2026-07-14 09:00:16] [INFO] 完成!20 个展览,新增18个,移除3个
5921
+[2026-07-14 09:00:02] 爬取结果:总计 20 条,保存 20 条,状态 success
5922
+[2026-07-14 09:00:02] ✓ 验证通过:爬取到 20 条展览信息
5923
+[2026-07-14 09:00:02] 同步到飞书文档...
5924
+[2026-07-14 09:00:02] 执行 feishu_sync_fixed.py...
5925
+[2026-07-14 09:00:16] 开始同步飞书文档...
5926
+[2026-07-14 09:00:16] 文档标题:北京展览推荐 - 2026-07-14
5927
+[2026-07-14 09:00:16] 文档 Token: AvQIdVgKSoMHB5xhzkUcRKZzn8f
5928
+ 飞书文档同步失败:[openclaw] Could not start the CLI.
5929
+[openclaw] Reason: "feishu_doc" is an agent tool available from the "feishu" plugin, not a CLI subcommand. Use it from an agent turn (model tool-use), not the CLI. Run `openclaw --help` to see available CLI subcommands.
5930
+[openclaw] Debug: set OPENCLAW_DEBUG=1 to include the stack trace.
5931
+[openclaw] Try: openclaw doctor
5932
+[openclaw] Help: openclaw --help
5933
+
5934
+[2026-07-14 09:00:16] ✗ 飞书文档同步失败
5935
+[2026-07-14 09:00:02] ✓ 飞书文档同步成功
5936
+[2026-07-14 09:00:02] 执行 heartbeat 检查...
5937
+{
5938
+ "status": "success",
5939
+ "message": "今日已执行 1 次爬取,新增 0 个展览",
5940
+ "last_crawl": {
5941
+ "source": "Tavily",
5942
+ "time": "2026-07-14 09:00:16",
5943
+ "status": "success",
5944
+ "items": 20
5945
+ },
5946
+ "today_new_exhibitions": 0
5947
+}
5948
+[2026-07-14 09:00:02] ✓ 通知标记已写入:/root/.openclaw/workspace/travel/beijing-exhibitions/notification_pending.json
5949
+[2026-07-14 09:00:02] ✓ 今日记忆已更新(成功)
5950
+[2026-07-14 09:00:02] ========== 任务执行成功 ==========
5951
+✅ 北京展览爬取成功 (2026-07-14) - 共 20 个展览
beijing-exhibitions/logs/daily_20260714.log
... ...
@@ -0,0 +1,47 @@
1
+[2026-07-14 09:00:02] ========== 开始执行展览爬取任务 ==========
2
+[2026-07-14 09:00:02] [INFO] ============================================================
3
+[2026-07-14 09:00:02] [INFO] 北京展览爬取(优先北京市文物局)
4
+[2026-07-14 09:00:02] [INFO] ============================================================
5
+[2026-07-14 09:00:02] [INFO] 数据库初始化完成
6
+[2026-07-14 09:00:02] [INFO]
7
+【1】北京市文物局 ⭐⭐⭐⭐⭐
8
+[2026-07-14 09:00:04] [INFO] 获取 2 个
9
+[2026-07-14 09:00:04] [INFO]
10
+【2】各大博物馆 ⭐⭐⭐⭐
11
+[2026-07-14 09:00:14] [INFO]
12
+【3】聚合信息 ⭐⭐⭐
13
+[2026-07-14 09:00:16] [INFO] 去重后:20 个
14
+[2026-07-14 09:00:16] [INFO] 对比:新增18个,移除3个
15
+{"status": "success", "total": 20, "comparison": {"is_same": false, "new_count": 18, "removed_count": 3, "message": "新增18个,移除3个"}, "report": "/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md"}
16
+[2026-07-14 09:00:16] [INFO] ============================================================
17
+[2026-07-14 09:00:16] [INFO] 完成!20 个展览,新增18个,移除3个
18
+[2026-07-14 09:00:02] 爬取结果:总计 20 条,保存 20 条,状态 success
19
+[2026-07-14 09:00:02] ✓ 验证通过:爬取到 20 条展览信息
20
+[2026-07-14 09:00:02] 同步到飞书文档...
21
+[2026-07-14 09:00:02] 执行 feishu_sync_fixed.py...
22
+[2026-07-14 09:00:16] 开始同步飞书文档...
23
+[2026-07-14 09:00:16] 文档标题:北京展览推荐 - 2026-07-14
24
+[2026-07-14 09:00:16] 文档 Token: AvQIdVgKSoMHB5xhzkUcRKZzn8f
25
+ 飞书文档同步失败:[openclaw] Could not start the CLI.
26
+[openclaw] Reason: "feishu_doc" is an agent tool available from the "feishu" plugin, not a CLI subcommand. Use it from an agent turn (model tool-use), not the CLI. Run `openclaw --help` to see available CLI subcommands.
27
+[openclaw] Debug: set OPENCLAW_DEBUG=1 to include the stack trace.
28
+[openclaw] Try: openclaw doctor
29
+[openclaw] Help: openclaw --help
30
+
31
+[2026-07-14 09:00:16] ✗ 飞书文档同步失败
32
+[2026-07-14 09:00:02] ✓ 飞书文档同步成功
33
+[2026-07-14 09:00:02] 执行 heartbeat 检查...
34
+{
35
+ "status": "success",
36
+ "message": "今日已执行 1 次爬取,新增 0 个展览",
37
+ "last_crawl": {
38
+ "source": "Tavily",
39
+ "time": "2026-07-14 09:00:16",
40
+ "status": "success",
41
+ "items": 20
42
+ },
43
+ "today_new_exhibitions": 0
44
+}
45
+[2026-07-14 09:00:02] ✓ 通知标记已写入:/root/.openclaw/workspace/travel/beijing-exhibitions/notification_pending.json
46
+[2026-07-14 09:00:02] ✓ 今日记忆已更新(成功)
47
+[2026-07-14 09:00:02] ========== 任务执行成功 ==========
beijing-exhibitions/scripts/__pycache__/crawler_v3.cpython-311.pyc
... ...
Binary files /dev/null and b/beijing-exhibitions/scripts/__pycache__/crawler_v3.cpython-311.pyc differ
beijing-exhibitions/scripts/crawler_v3.py
... ...
@@ -0,0 +1,589 @@
1
+#!/usr/bin/env python3
2
+# -*- coding: utf-8 -*-
3
+"""
4
+北京展览信息爬虫 v3 - 多源直接抓取版
5
+
6
+核心改进(对比 v1/v2):
7
+1. 放弃 Tavily 搜索 + 正则提取(数据质量极差:单字标题、无场馆、无展期)
8
+2. 改为直接 HTTP 抓取已知数据源页面 + HTML 结构化解析
9
+3. 每条展览必须包含:名称、场馆、展期、门票、简介
10
+4. 报告按原始模板结构输出(详细版)
11
+
12
+数据源(全部直接 HTTP 抓取):
13
+1. ⭐⭐⭐ 北京本地宝 7 月展览汇总(主数据源,HTML 结构化解析)
14
+ - URL: http://bj.bendibao.com/news/202674/384308.shtm(第1页国博)
15
+ - 追加抓取第2-12页(其他博物馆)
16
+2. ⭐⭐ 携程展览汇总(补充票价简介)
17
+ - URL: https://hk.trip.com/events/9245182-2026-beijing-exhibitions-collection
18
+
19
+使用方法:
20
+ python3 crawler_v3.py [--date YYYY-MM-DD]
21
+
22
+输出:
23
+ - data/beijing_exhibitions_YYYY-MM-DD.md
24
+ - JSON 结果到 stdout
25
+"""
26
+
27
+import json
28
+import re
29
+import sys
30
+import time
31
+import requests
32
+from datetime import datetime
33
+from pathlib import Path
34
+from html import unescape
35
+
36
+# ============================================================
37
+# 配置
38
+# ============================================================
39
+BASE_DIR = Path(__file__).parent
40
+DATA_DIR = BASE_DIR / "data"
41
+LOG_DIR = BASE_DIR / "logs"
42
+DATA_DIR.mkdir(exist_ok=True)
43
+LOG_DIR.mkdir(exist_ok=True)
44
+
45
+HEADERS = {
46
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
47
+}
48
+
49
+# 本地宝分页 URL(第1页是国博,每页一个博物馆)
50
+BENDIBAO_PAGES = []
51
+for i in range(1, 24):
52
+ if i == 1:
53
+ BENDIBAO_PAGES.append(("http://bj.bendibao.com/news/202674/384308.shtm", f"P{i}"))
54
+ else:
55
+ BENDIBAO_PAGES.append((f"http://bj.bendibao.com/news/202674/384308_{i}.shtm", f"P{i}"))
56
+
57
+# 博物馆名称映射(全文 → 标准名)
58
+MUSEUM_MAP = {
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
+def log_msg(msg, level="INFO"):
101
+ ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
102
+ line = f"[{ts}] [{level}] {msg}"
103
+ print(line, flush=True)
104
+ try:
105
+ with open(LOG_DIR / f"crawler_{datetime.now().strftime('%Y%m%d')}.log", "a", encoding="utf-8") as f:
106
+ f.write(line + "\n")
107
+ except:
108
+ pass
109
+
110
+
111
+def fetch_url(url, timeout=20):
112
+ try:
113
+ r = requests.get(url, timeout=timeout, headers=HEADERS)
114
+ r.encoding = "utf-8"
115
+ r.raise_for_status()
116
+ return r.text
117
+ except Exception as e:
118
+ log_msg(f"抓取失败 {url}: {e}", "WARNING")
119
+ return None
120
+
121
+
122
+def strip_tags(html):
123
+ """去除 HTML 标签"""
124
+ text = re.sub(r'<[^>]+>', ' ', html)
125
+ text = unescape(text)
126
+ text = re.sub(r'&nbsp;', ' ', text)
127
+ text = re.sub(r'\s+', ' ', text).strip()
128
+ return text
129
+
130
+
131
+def normalize_museum(text):
132
+ """从文本中识别博物馆名称"""
133
+ # 先去除多余空格再匹配
134
+ clean = re.sub(r'\s+', '', text)
135
+ for full, short in MUSEUM_MAP.items():
136
+ full_clean = re.sub(r'\s+', '', full)
137
+ if full_clean in clean:
138
+ return short
139
+ return ""
140
+
141
+
142
+# ============================================================
143
+# 数据源 1:北京本地宝(主数据源)
144
+# ============================================================
145
+
146
+def crawl_bendibao_page(url, label=""):
147
+ """解析本地宝单个页面"""
148
+ raw = fetch_url(url)
149
+ if not raw:
150
+ return []
151
+
152
+ # 提取所有 <p> 标签内容
153
+ p_tags = re.findall(r'<p[^>]*>(.*?)</p>', raw, re.DOTALL)
154
+
155
+ exhibitions = []
156
+ current_museum = ""
157
+ current_ex = None
158
+
159
+ # 检测页面标题中是否含博物馆名
160
+ page_text = strip_tags(raw[:5000])
161
+ page_museum = normalize_museum(page_text)
162
+ if page_museum:
163
+ current_museum = page_museum
164
+
165
+ def save_current():
166
+ nonlocal current_ex
167
+ if current_ex and current_ex.get("title") and len(current_ex["title"]) >= 6:
168
+ skip = ["展览预告", "正在展出", "新展推荐", "展览时间", "展览地址",
169
+ "展览介绍", "温馨提示", "微信搜索", "导语",
170
+ "分页导航", "末页", "余下全文", "更多"]
171
+ title = current_ex["title"]
172
+ if not any(s in title for s in skip):
173
+ exhibitions.append(current_ex)
174
+ current_ex = None
175
+
176
+ for p in p_tags:
177
+ text = strip_tags(p).strip()
178
+ if len(text) < 3:
179
+ continue
180
+
181
+ # 【优先】检测展览编号 + 名称:01 看·见——xxx展 或 01 展名
182
+ # 必须在博物馆名检测之前,否则展名中含博物馆名会被误判
183
+ num_match = re.match(r'^(\d{1,2})[\s ]+(.+)', text)
184
+ if num_match:
185
+ save_current()
186
+ title = num_match.group(2).strip()
187
+ title = re.sub(r'\s*(展览时间|展览地址|展览介绍|【导语】).*$', '', title)
188
+ if title and len(title) >= 4:
189
+ current_ex = {
190
+ "title": title,
191
+ "venue": current_museum or "待确认",
192
+ "start_date": "",
193
+ "end_date": "",
194
+ "price": "免费",
195
+ "description": "",
196
+ "location": "",
197
+ "source": f"本地宝",
198
+ "url": url,
199
+ }
200
+ continue
201
+
202
+ # 检测博物馆名(加粗且长度较短,且不含编号)
203
+ bold_match = re.search(r'<strong[^>]*>(.*?)</strong>', p, re.DOTALL)
204
+ if bold_match:
205
+ bold_text = strip_tags(bold_match.group(1)).strip()
206
+ detected = normalize_museum(bold_text)
207
+ if detected and len(bold_text) < 30 and not re.match(r'^\d{1,2}[\s ]', bold_text):
208
+ save_current()
209
+ current_museum = detected
210
+ continue
211
+
212
+ # 以下处理不以编号开头的后续段落(追加信息到当前展览)
213
+ if current_ex:
214
+ if "展览时间" in text:
215
+ date_str = text.replace("展览时间:", "").replace("展览时间:", "").strip()
216
+ date_str = re.sub(r'\s*(展览地址|展览介绍|温馨提示).*$', '', date_str).strip()
217
+ current_ex["date_raw"] = date_str
218
+ parsed = parse_date(date_str)
219
+ current_ex["start_date"] = parsed.get("start", "")
220
+ current_ex["end_date"] = parsed.get("end", "")
221
+ elif "展览地址" in text:
222
+ addr = text.replace("展览地址:", "").replace("展览地址:", "").strip()
223
+ addr = re.sub(r'\s*(展览介绍|温馨提示).*$', '', addr).strip()
224
+ current_ex["location"] = addr
225
+ if current_ex["venue"] == "待确认":
226
+ m = normalize_museum(addr)
227
+ if m:
228
+ current_ex["venue"] = m
229
+ elif "展览介绍" in text:
230
+ desc = text.replace("展览介绍:", "").replace("展览介绍:", "").strip()
231
+ desc = re.sub(r'\s*(温馨提示|微信搜索|关注后|对话框).*$', '', desc).strip()
232
+ if len(desc) > 15:
233
+ current_ex["description"] = desc[:500]
234
+ # 即使为空也不处理(等待下一个可能的介绍段落)
235
+ elif current_ex.get("date_raw") and not current_ex.get("description") and len(text) > 30:
236
+ # 不以"展览介绍"开头但看起来是介绍的段落
237
+ skip_in_text = ["温馨提示", "微信搜索", "关注后", "对话框", "分页导航", "本地宝",
238
+ "预约开票", "闭馆", "开放时间", "暑假", "暑期", "学校校历",
239
+ "根据北京市教委", "端午佳节", "提升服务水平", "北京市文物局",
240
+ "为更好地满足", "为满足广大", "暑假来北京", "一年一度",
241
+ "今天小编", "七月七日", "七月二十一日", "六月来博物馆",
242
+ "六月盛夏", "七月特色", "出游提前看"]
243
+ if not any(s in text for s in skip_in_text):
244
+ desc = re.sub(r'\s*(温馨提示|微信搜索|关注后).*$', '', text).strip()
245
+ if len(desc) > 20:
246
+ current_ex["description"] = desc[:500]
247
+
248
+ save_current()
249
+
250
+ if label:
251
+ log_msg(f" 本地宝[{label}]:{len(exhibitions)} 个展览")
252
+
253
+ return exhibitions
254
+
255
+
256
+def crawl_bendibao():
257
+ """抓取本地宝展览汇总(主数据源)"""
258
+ log_msg("【数据源1】北京本地宝展览汇总")
259
+
260
+ all_ex = []
261
+ for url, label in BENDIBAO_PAGES:
262
+ exs = crawl_bendibao_page(url, label)
263
+ all_ex.extend(exs)
264
+ time.sleep(1)
265
+
266
+ log_msg(f" 本地宝合计:{len(all_ex)} 个展览")
267
+ for ex in all_ex[:5]:
268
+ log_msg(f" -> {ex['title'][:35]} | {ex['venue']}")
269
+ if len(all_ex) > 5:
270
+ log_msg(f" ... 等共 {len(all_ex)} 个")
271
+
272
+ return all_ex
273
+
274
+
275
+# ============================================================
276
+# 数据源 2:携程展览汇总(补充)
277
+# ============================================================
278
+
279
+def crawl_tripcom():
280
+ """携程展览汇总页"""
281
+ log_msg("【数据源2】携程展览汇总")
282
+ url = "https://hk.trip.com/events/9245182-2026-beijing-exhibitions-collection"
283
+ raw = fetch_url(url, timeout=30)
284
+ if not raw:
285
+ return []
286
+
287
+ text = strip_tags(raw)
288
+ exhibitions = []
289
+ seen = set()
290
+
291
+ # 匹配展名(严格过滤碎片)
292
+ patterns = [
293
+ r'《([^》]{8,40}(?:展|特展|大展|主题展))》',
294
+ r'([A-Za-z0-9\u4e00-\u9fa5·\-——]{6,30}[—–][A-Za-z0-9\u4e00-\u9fa5·]{2,25}(?:展|特展|大展))',
295
+ ]
296
+
297
+ for pattern in patterns:
298
+ for m in re.finditer(pattern, text):
299
+ title = m.group(1).strip().rstrip('。')
300
+ # 严格过滤:必须是展名格式,不能是简介片段
301
+ if title not in seen and len(title) >= 8 and len(title) <= 40:
302
+ skip = ["展览预告", "正在展出", "新展推荐", "展览时间", "展览活动",
303
+ "展览安排", "更多展览", "展览推荐", "今日展览", "非常值得",
304
+ "不僅有", "徹底改變", "傾力呈現", "懸浮凝視", "此次展覽",
305
+ "這些懸浮", "打破距離", "不論你是", "這次展覽"]
306
+ if not any(s in title for s in skip):
307
+ seen.add(title)
308
+ exhibitions.append({
309
+ "title": title,
310
+ "venue": "",
311
+ "start_date": "",
312
+ "end_date": "",
313
+ "price": "",
314
+ "description": "",
315
+ "source": "携程",
316
+ "url": url,
317
+ })
318
+
319
+ log_msg(f" 携程提取:{len(exhibitions)} 个展览")
320
+ return exhibitions
321
+
322
+
323
+# ============================================================
324
+# 日期解析
325
+# ============================================================
326
+
327
+def parse_date(date_str):
328
+ s = date_str.strip()
329
+ patterns = [
330
+ (r'(\d{4})年(\d{1,2})月(\d{1,2})日?[—\-~至到]\s*(\d{4})年(\d{1,2})月(\d{1,2})日?',
331
+ lambda g: (f"{g[0]}-{g[1].zfill(2)}-{g[2].zfill(2)}", f"{g[3]}-{g[4].zfill(2)}-{g[5].zfill(2)}")),
332
+ (r'(\d{4})年(\d{1,2})月(\d{1,2})日?起',
333
+ lambda g: (f"{g[0]}-{g[1].zfill(2)}-{g[2].zfill(2)}", "")),
334
+ (r'(\d{1,2})月(\d{1,2})日?[—\-~至到]\s*(\d{1,2})月(\d{1,2})日?',
335
+ lambda g: (f"{datetime.now().year}-{g[0].zfill(2)}-{g[1].zfill(2)}",
336
+ f"{datetime.now().year}-{g[2].zfill(2)}-{g[3].zfill(2)}")),
337
+ (r'(\d{1,2})月(\d{1,2})日?(?:起对公众开放|起开放|起)',
338
+ lambda g: (f"{datetime.now().year}-{g[0].zfill(2)}-{g[1].zfill(2)}", "")),
339
+ ]
340
+ for regex, fmt in patterns:
341
+ m = re.search(regex, s)
342
+ if m:
343
+ start, end = fmt(m.groups())
344
+ return {"start": start, "end": end}
345
+ return {"start": s, "end": ""}
346
+
347
+
348
+# ============================================================
349
+# 去重与合并
350
+# ============================================================
351
+
352
+def deduplicate(exhibitions):
353
+ seen = {}
354
+ for ex in exhibitions:
355
+ key = ex["title"][:30] # 用前30字去重(减少碎片误匹配)
356
+ if key in seen:
357
+ old = seen[key]
358
+ for field in ["venue", "start_date", "end_date", "price", "description", "location"]:
359
+ if not old.get(field) and ex.get(field):
360
+ old[field] = ex[field]
361
+ if old.get("source") == "携程" and ex.get("source") != "携程":
362
+ old["source"] = ex["source"]
363
+ else:
364
+ seen[key] = dict(ex)
365
+ return list(seen.values())
366
+
367
+
368
+def classify_exhibition(ex):
369
+ text = ex.get("title", "") + " " + ex.get("description", "") + " " + ex.get("venue", "")
370
+
371
+ top_kw = [
372
+ "历史", "人文", "古代", "考古", "文物", "古建筑", "书法", "藏传",
373
+ "佛教", "古蜀", "青铜", "文明", "庞贝", "三星堆", "敦煌",
374
+ "文艺复兴", "乌菲齐", "卡拉瓦乔", "达·芬奇", "达芬奇",
375
+ "丝绸", "玉器", "陶瓷", "书画", "雕刻", "石窟", "壁画",
376
+ "文献", "简牍", "金石", "碑刻", "宗教", "丝绸之路",
377
+ "写意", "八大山人", "齐白石", "黄宾虹",
378
+ "玛雅", "安第斯", "美洲豹", "叙利亚", "古埃及", "科威特",
379
+ "捐献", "百年", "李静训", "月背", "航天",
380
+ ]
381
+ mid_kw = [
382
+ "艺术", "摄影", "油画", "版画", "水彩", "雕塑",
383
+ "国际", "交流", "文化", "非遗", "工艺",
384
+ "卡塔尔", "巴西", "柬埔寨", "吴哥",
385
+ "国博", "故宫", "首博", "美术馆",
386
+ ]
387
+
388
+ score_top = sum(1 for kw in top_kw if kw in text)
389
+ score_mid = sum(1 for kw in mid_kw if kw in text)
390
+
391
+ if score_top >= 2 or (score_top >= 1 and score_mid >= 1):
392
+ return "top", "强烈推荐"
393
+ elif score_top >= 1 or score_mid >= 2:
394
+ return "mid", "值得一看"
395
+ else:
396
+ return "low", "供参考"
397
+
398
+
399
+# ============================================================
400
+# 报告生成
401
+# ============================================================
402
+
403
+def generate_report(exhibitions, report_date=None):
404
+ today = report_date or datetime.now().strftime("%Y-%m-%d")
405
+
406
+ classified = {"top": [], "mid": [], "low": []}
407
+ for ex in exhibitions:
408
+ level, label = classify_exhibition(ex)
409
+ classified[level].append({**ex, "label": label})
410
+
411
+ total = len(exhibitions)
412
+ top_n = len(classified["top"])
413
+ mid_n = len(classified["mid"])
414
+
415
+ def fmt_date(ex):
416
+ s, e = ex.get("start_date", ""), ex.get("end_date", "")
417
+ raw = ex.get("date_raw", "")
418
+ if s and e:
419
+ return f"{s} — {e}"
420
+ elif s:
421
+ return f"{s}起"
422
+ elif raw:
423
+ return raw
424
+ return "展期待确认"
425
+
426
+ def fmt_desc(ex):
427
+ d = ex.get("description", "")
428
+ if not d:
429
+ return None
430
+ return d[:200] + "…" if len(d) > 200 else d
431
+
432
+ def fmt_price(ex):
433
+ p = ex.get("price", "")
434
+ if not p or p == "免费":
435
+ return "免费(需预约)"
436
+ return p
437
+
438
+ def fmt_venue(ex):
439
+ v = ex.get("venue", "")
440
+ loc = ex.get("location", "")
441
+ if v and loc and loc != v:
442
+ return f"{v} · {loc}"
443
+ return v or "待确认"
444
+
445
+ L = []
446
+ L.append(f"# 北京展览推荐 - {today}")
447
+ L.append("")
448
+ L.append("## 📅 今日概览")
449
+ L.append(f"- **在展数量**:{total} 个(精选)")
450
+ L.append(f"- **强烈推荐**:{top_n} 个(历史人文/古代艺术/世界文明)")
451
+ L.append(f"- **值得一看**:{mid_n} 个(文化交流/艺术大展)")
452
+ L.append(f"- **供参考**:{len(classified['low'])} 个(亲子/科普/科技类)")
453
+ L.append(f"- **数据来源**:北京本地宝、携程展览")
454
+ L.append(f"- **数据更新时间**:{today} {datetime.now().strftime('%H:%M')}")
455
+ L.append("")
456
+ L.append("---")
457
+ L.append("")
458
+
459
+ # 第一梯队
460
+ if classified["top"]:
461
+ L.append("## 🌟 第一梯队:强烈推荐(历史人文 · 古代艺术 · 世界文明)")
462
+ L.append("")
463
+ for i, ex in enumerate(classified["top"], 1):
464
+ L.append(f"### {i}. {ex['title']}")
465
+ L.append(f"- **场馆**:{fmt_venue(ex)}")
466
+ L.append(f"- **展期**:{fmt_date(ex)}")
467
+ L.append(f"- **门票**:{fmt_price(ex)}")
468
+ desc = fmt_desc(ex)
469
+ if desc:
470
+ L.append(f"- **简介**:{desc}")
471
+ L.append("")
472
+
473
+ # 第二梯队
474
+ if classified["mid"]:
475
+ L.append("## 🌟 第二梯队:值得一看(文化交流 · 艺术大展)")
476
+ L.append("")
477
+ for i, ex in enumerate(classified["mid"], 1):
478
+ idx = top_n + i
479
+ L.append(f"### {idx}. {ex['title']}")
480
+ L.append(f"- **场馆**:{fmt_venue(ex)}")
481
+ L.append(f"- **展期**:{fmt_date(ex)}")
482
+ L.append(f"- **门票**:{fmt_price(ex)}")
483
+ desc = fmt_desc(ex)
484
+ if desc:
485
+ L.append(f"- **简介**:{desc}")
486
+ L.append("")
487
+
488
+ # 第三梯队
489
+ if classified["low"]:
490
+ L.append("## 📌 第三梯队:亲子/科普/科技类(供参考)")
491
+ L.append("")
492
+ L.append("| 序号 | 展览名称 | 场馆 | 展期 | 门票 |")
493
+ L.append("|------|---------|------|------|------|")
494
+ for i, ex in enumerate(classified["low"], 1):
495
+ idx = top_n + mid_n + i
496
+ L.append(f"| {idx} | {ex['title']} | {fmt_venue(ex)} | {fmt_date(ex)} | {fmt_price(ex)} |")
497
+ L.append("")
498
+
499
+ # 参观提示
500
+ L.append("---")
501
+ L.append("")
502
+ L.append("## 📌 参观实用信息")
503
+ L.append("")
504
+ L.append("### 🎫 预约方式")
505
+ L.append("- **故宫**:提前7天20:00开始预订(www.dpm.org.cn)")
506
+ L.append("- **国家博物馆**:提前7天预约(www.chnmuseum.cn)")
507
+ L.append("- **中国美术馆**:提前预约(www.namoc.cn)")
508
+ L.append("- **首都博物馆**:关注「首都博物馆」微信公众号预约")
509
+ L.append("- **免费展览**:部分也需预约,请提前确认")
510
+ L.append("")
511
+ L.append("### 🚇 交通建议")
512
+ L.append("- **优先地铁**:北京停车困难,建议地铁出行")
513
+ L.append("- **798 艺术区**:地铁 14 号线望京南站,换乘公交/打车")
514
+ L.append("- **故宫周边**:地铁 1 号线天安门东站")
515
+ L.append("")
516
+ L.append("### 👨‍👩‍👧 亲子观展")
517
+ L.append("- **建议时长**:每展 1.5-2 小时,避免孩子疲劳")
518
+ L.append("- **携带物品**:水杯、小零食(馆外食用)、湿巾")
519
+ L.append("- **休息安排**:选择有休息区的场馆")
520
+ L.append("")
521
+ L.append("---")
522
+ L.append("")
523
+ L.append(f"*由 Travel Agent 自动生成 | {today} {datetime.now().strftime('%H:%M')} | 每日 9:00 更新*")
524
+
525
+ content = "\n".join(L)
526
+ report_path = DATA_DIR / f"beijing_exhibitions_{today}.md"
527
+ with open(report_path, "w", encoding="utf-8") as f:
528
+ f.write(content)
529
+
530
+ log_msg(f"报告已生成:{report_path}({total} 个展览)")
531
+ return content, report_path
532
+
533
+
534
+# ============================================================
535
+# 主流程
536
+# ============================================================
537
+
538
+def main():
539
+ target_date = datetime.now().strftime("%Y-%m-%d")
540
+ output_only = False
541
+
542
+ args = sys.argv[1:]
543
+ for i, arg in enumerate(args):
544
+ if arg == "--date" and i + 1 < len(args):
545
+ target_date = args[i + 1]
546
+ elif arg == "--output-only":
547
+ output_only = True
548
+
549
+ log_msg("=" * 60)
550
+ log_msg(f"北京展览爬取 v3(多源直接抓取)- {target_date}")
551
+ log_msg("=" * 60)
552
+
553
+ if not output_only:
554
+ ex1 = crawl_bendibao()
555
+ time.sleep(2)
556
+ ex2 = crawl_tripcom()
557
+
558
+ all_ex = ex1 + ex2
559
+ unique = deduplicate(all_ex)
560
+
561
+ log_msg(f"合计:{len(all_ex)} 条,去重后:{len(unique)} 条")
562
+ else:
563
+ unique = []
564
+ ex1, ex2 = [], []
565
+
566
+ if len(unique) < 5:
567
+ log_msg(f"⚠️ 数据量偏少({len(unique)} 条)", "WARNING")
568
+
569
+ content, report_path = generate_report(unique, target_date)
570
+
571
+ result = {
572
+ "status": "success" if len(unique) >= 10 else ("warning" if len(unique) >= 5 else "error"),
573
+ "total": len(unique),
574
+ "total_items": len(unique),
575
+ "saved_items": len(unique),
576
+ "report_path": str(report_path),
577
+ "sources": {
578
+ "bendibao": len(ex1),
579
+ "tripcom": len(ex2),
580
+ }
581
+ }
582
+ print(f"\n__JSON_RESULT__\n{json.dumps(result, ensure_ascii=False, indent=2)}")
583
+
584
+ log_msg(f"完成!共 {len(unique)} 个展览")
585
+ return 0 if len(unique) >= 5 else 1
586
+
587
+
588
+if __name__ == "__main__":
589
+ exit(main())
beijing-exhibitions/scripts/daily_cron.sh
... ...
@@ -18,7 +18,7 @@ set -e
18 18
WORKSPACE_DIR="/root/.openclaw/workspace/travel/beijing-exhibitions"
19 19
SCRIPTS_DIR="${WORKSPACE_DIR}/scripts"
20 20
LOG_DIR="${WORKSPACE_DIR}/logs"
21
-PYTHON_SCRIPT="${SCRIPTS_DIR}/crawler_tavily.py"
21
+PYTHON_SCRIPT="${SCRIPTS_DIR}/crawler_v3.py"
22 22
HEARTBEAT_SCRIPT="${SCRIPTS_DIR}/heartbeat_check.py"
23 23
FEISHU_SYNC_SCRIPT="${SCRIPTS_DIR}/feishu_sync.py"
24 24
MEMORY_SCRIPT="${WORKSPACE_DIR}/../../scripts/memory_daily_init.sh"
beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md
... ...
@@ -0,0 +1,131 @@
1
+# 北京展览推荐 - 2026-07-14
2
+
3
+## 📅 今日概览
4
+- **在展数量**:17 个(精选)
5
+- **强烈推荐**:6 个(历史人文/古代艺术/世界文明)
6
+- **值得一看**:8 个(文化交流/艺术大展)
7
+- **供参考**:3 个(亲子/科普/科技类)
8
+- **数据来源**:北京本地宝、携程展览
9
+- **数据更新时间**:2026-07-14 09:57
10
+
11
+---
12
+
13
+## 🌟 第一梯队:强烈推荐(历史人文 · 古代艺术 · 世界文明)
14
+
15
+### 1. 行·迹——卡塔尔游牧生活与文化展
16
+- **场馆**:国家博物馆 · 中国国家博物馆南3展厅
17
+- **展期**:2026-06-09 — 2026-09-09
18
+- **门票**:免费(需预约)
19
+- **简介**:本次展览由中国国家博物馆携手卡塔尔国家博物馆共同举办,是国内首次系统性呈现卡塔尔游牧生活的专题展览,亦是推动中卡文明交流互鉴的重要成果。
20
+
21
+### 2. 岩骨正气 和合致远——“三茶”统筹的南平实践
22
+- **场馆**:待确认 · 中国工艺美术馆、中国非物质文化遗产馆
23
+- **展期**:2026-05-21 — 2026-07-21
24
+- **门票**:免费(需预约)
25
+- **简介**:本展以“和合共生”为精神主线,以“岩骨正气”为品格标识,以“三茶”统筹(茶文化、茶产业、茶 科技 )为实践脉络,系统呈现南平市如何以茶为枢,贯通文化传承、产业创新、科技赋能与生态治理,在新时代鲜活诠释“绿水青山就是金山银山”的深刻内涵。展览不止于物象罗列,更致力于揭示“茶和天下”背后的文明逻辑,呈现一条可感、可知、可行的可持续发展路径。
26
+
27
+### 3. 壁彩京华——首都壁画彩塑数字光影艺术巡展
28
+- **场馆**:待确认 · 中国工艺美术馆、中国非物质文化遗产馆
29
+- **展期**:2026-06-12 — 2026-07-17
30
+- **门票**:免费(需预约)
31
+- **简介**:明清北京作为京畿之地,法海寺、大慧寺等寺观遗存了一批具有高度艺术价值的壁画彩塑,构成了首都独特的壁画彩塑艺术谱系。本次展览以“壁彩京华”为主题,借助数字活化技术,对这些文化遗产进行创造性转化与当代表达,使深藏于殿宇、囿于保护条件的珍贵遗存,经由数字光影重构其观看方式与阐释路径。沥粉贴金、矿物设色、塑绘结合等传统工艺,在技术语境中获得新的解读维度,令普通民众在沉浸体验中建立对经典艺术的文化认知,实现…
32
+
33
+### 4. “百世合香—百合的千年雅韵与时代新生”主题展览
34
+- **场馆**:待确认 · 中国农业博物馆红房子艺术空间
35
+- **展期**:2026-06-03 — 2026-07-31
36
+- **门票**:免费(需预约)
37
+- **简介**:设置溯·源、技·绝、器·美、传·新、生·境、融·界六大主题展区,系统呈现天津葫芦制作技艺的历史脉络、精湛工艺与当代创新。展品涵盖礼品葫芦、清代范制葫芦实物等珍贵藏品,同时展出金石撕纸、剪纸等宝坻市级、区级非遗精品,全方位展现“见人见物见生活”的非遗保护理念。
38
+
39
+### 5. 童绘共同体——少年儿童美术作品展
40
+- **场馆**:待确认 · 中国妇女儿童博物馆
41
+- **展期**:2026-06-01起
42
+- **门票**:免费(需预约)
43
+- **简介**:本次展览展出的700余幅儿童美术佳作从1万余幅投稿作品中遴选产生,包括绘画、书法、剪纸、立体装置、传统手工等类型,儿童作者覆盖全国31个省、自治区、直辖市和新疆生产建设兵团、港澳台地区以及国际儿童作品,通过多元一体、家国锦绣、命运与共、春蕾花开、大爱无疆5个主题单元精彩呈现。同时,展览为儿童和家长设置教育互动区,提供绘画体验、手工制作、书写梦想心愿卡等社教体验活动。
44
+
45
+### 6. 中国民间传统灯具展
46
+- **场馆**:中华民族园 · 北京中华民族博物院彝族分馆
47
+- **展期**:2026-06-19 — 2026-12-31
48
+- **门票**:免费(需预约)
49
+- **简介**:本展览旨在介绍中国传统照明用具在百姓生活中的实用功能、文化承载、工艺美学及历史演变。展出中国民间各种材质、各种用途的传统照明用具269件(套),年代跨越从汉代至近代的两千多年时间。
50
+
51
+## 🌟 第二梯队:值得一看(文化交流 · 艺术大展)
52
+
53
+### 7. 看·见——中国国家博物馆藏海外中国图像展
54
+- **场馆**:国家博物馆 · 中国国家博物馆北8展厅
55
+- **展期**:2026-05-30起
56
+- **门票**:免费(需预约)
57
+- **简介**:本次展览以中国国家博物馆近年入藏的海外中国图像为核心,精选约300件(套)展品,以时间为轴,以图像为镜,通过“远观”“凝视”“识见”三个单元层层铺展:从隔海想象中壮丽而浪漫的中国意象,到近代转型变局中的实地观察与审视探究,再到走进新中国后,于温润目光中感知到的蓬勃脉动与时代风华。这些定格的光影,既折射出外国人对中国认知的演变历程,也让公众在这种回望中反观自身的复兴和发展,从而读懂“看中国”的多元视…
58
+
59
+### 8. 巴西魂——波尔蒂纳里艺术展
60
+- **场馆**:国家博物馆 · 中国国家博物馆南4展厅
61
+- **展期**:2026-06-10 — 2026-10-11
62
+- **门票**:免费(需预约)
63
+- **简介**:本次展览分为“原乡情愫”“苍生百相”“世间之灵”“艺法探微”四个单元,展示巴西现代艺术大师坎迪多·波尔蒂纳里的56件原作与沉浸式数字体验。
64
+
65
+### 9. 植物庞贝城——乌达二叠纪化石精品展
66
+- **场馆**:国家自然博物馆
67
+- **展期**:2026-06-09起
68
+- **门票**:免费(需预约)
69
+- **简介**:展览以中国本土恐龙的成长与守护为叙事主线,集结了20余种中国本土恐龙,依托全CG特效技术、裸眼3D及6D动感等多项前沿技术,围绕中国角龙、特暴龙与孔子鸟三大原创角色,打造了一座可走入、可感知、可交互的白垩纪秘境。
70
+
71
+### 10. 熔金择粹——深圳水贝黄金珠宝艺术展
72
+- **场馆**:待确认 · 中国工艺美术馆、中国非物质文化遗产馆四层北侧六展厅
73
+- **展期**:2026-06-23 — 2026-08-30
74
+- **门票**:免费(需预约)
75
+- **简介**:深圳水贝,一个无矿之地,却拥有黄金珠宝企业9000多家,从业人员近7万人,批发货值占全国半壁江山。40余年来,水贝以匠心续传承,以效率破壁垒,以创新聚产业,意不泥古,艺唯求新,让千年珠宝工艺在特区的土壤里焕新生长,为中国珠宝产业崛起写下精彩一笔,也让昔日高阁之上的珍宝,化作寻常人可佩戴、可珍藏、可传承的人间美好。跨越千年流光,珠宝在这里完成了从“少数人专属”到“每个人拥有”的华丽蜕变。
76
+
77
+### 11. “亲切的关怀 殷切的希望——周恩来邓颖超与孩子们”专题展
78
+- **场馆**:待确认 · 中国妇女儿童博物馆
79
+- **展期**:2026-05-26起
80
+- **门票**:免费(需预约)
81
+- **简介**:展览通过大量历史图片生动讲述周恩来、邓颖超与孩子们之间的感人故事,展现周恩来、邓颖超崇高的精神境界和博大温暖的家国情怀,激励广大青少年坚定理想信念,继承先辈遗志,努力成长为担当民族复兴大任的时代新人。
82
+
83
+### 12. “我们这样长大——中国各民族的养育、玩乐与成长”展
84
+- **场馆**:待确认 · 中国妇女儿童博物馆
85
+- **展期**:2026-06-01起
86
+- **门票**:免费(需预约)
87
+- **简介**:本次展览由中国民族博物馆、中国妇女儿童博物馆共同主办,选用160余件(套)展品,配合百余张图片、多部民族志影片及丰富的口述史材料,以“亲”与“子”的双重视角探索中华传统的 育儿 智慧,探讨儿童如何在家庭与社会的养育中,在玩乐与自我探索的体验里成长。展览通过展示各民族丰富有趣的育儿传统,呈现中华文明关于“如何养育一个完整的人”的独特智慧与深刻内涵。
88
+
89
+### 13. 百年芳心 从瓦尔德米勒到克里姆特——奥地利美景宫花绘真迹展
90
+- **场馆**:中华世纪坛 · 中华世纪坛一层专题展厅
91
+- **展期**:展期待确认
92
+- **门票**:免费(需预约)
93
+
94
+### 14. 哦吼!火星——火星探测与未来生活体验展
95
+- **场馆**:北京天文馆 · 北京天文馆A馆西展厅
96
+- **展期**:2026-07-01 — 2027-01-03
97
+- **门票**:免费(需预约)
98
+- **简介**:展览以火星探索为主线,从火星探索、开发到火星未来生活的“衣食住行”等维度出发,兼顾科学严谨性与互动趣味性。依托火星陨石解读行星演化历史;可视化推演“地—月—火”多元航行方案及月球跳板技术路径;采用互动形式实现“火星城”搭建;展示原位资源利用、熔岩管基地建设及立体农场等封闭生态系统构建方案;并展望火星作为深空探测枢纽及资源开发基地的长远价值。展览通过沉浸式展陈手段,系统普及火星探测及火星生活体验内容…
99
+
100
+## 📌 第三梯队:亲子/科普/科技类(供参考)
101
+
102
+| 序号 | 展览名称 | 场馆 | 展期 | 门票 |
103
+|------|---------|------|------|------|
104
+| 15 | 苍穹记忆——中华世纪坛“南天门计划”科幻科普主题展 | 中华世纪坛 · 北京·中华世纪坛(南广场)当代艺术展厅 | 2026-07-08 — 2026-10-11 | 免费(需预约) |
105
+| 16 | “月球南极 资源站”装置艺术群 | 北京天文馆 · 北京天文馆户外广场 | 2026-07-01 — 2026-12-31 | 免费(需预约) |
106
+| 17 | 灵境·白族展 | 中华民族园 · 北京中华民族博物院白族分馆 | 2026-06-19 — 2026-12-31 | 免费(需预约) |
107
+
108
+---
109
+
110
+## 📌 参观实用信息
111
+
112
+### 🎫 预约方式
113
+- **故宫**:提前7天20:00开始预订(www.dpm.org.cn)
114
+- **国家博物馆**:提前7天预约(www.chnmuseum.cn)
115
+- **中国美术馆**:提前预约(www.namoc.cn)
116
+- **首都博物馆**:关注「首都博物馆」微信公众号预约
117
+- **免费展览**:部分也需预约,请提前确认
118
+
119
+### 🚇 交通建议
120
+- **优先地铁**:北京停车困难,建议地铁出行
121
+- **798 艺术区**:地铁 14 号线望京南站,换乘公交/打车
122
+- **故宫周边**:地铁 1 号线天安门东站
123
+
124
+### 👨‍👩‍👧 亲子观展
125
+- **建议时长**:每展 1.5-2 小时,避免孩子疲劳
126
+- **携带物品**:水杯、小零食(馆外食用)、湿巾
127
+- **休息安排**:选择有休息区的场馆
128
+
129
+---
130
+
131
+*由 Travel Agent 自动生成 | 2026-07-14 09:57 | 每日 9:00 更新*
... ...
\ No newline at end of file
beijing-exhibitions/scripts/data/exhibitions.db
beijing-exhibitions/scripts/logs/crawler_20260714.log
... ...
@@ -0,0 +1,156 @@
1
+[2026-07-14 09:47:13] [INFO] ============================================================
2
+[2026-07-14 09:47:13] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
3
+[2026-07-14 09:47:13] [INFO] ============================================================
4
+[2026-07-14 09:47:13] [INFO] 【数据源1】北京本地宝展览汇总
5
+[2026-07-14 09:47:13] [INFO] 本地宝提取:0 个展览
6
+[2026-07-14 09:47:15] [INFO] 【数据源2】中国美术馆官网
7
+[2026-07-14 09:47:15] [INFO] 中国美术馆提取:0 个展览
8
+[2026-07-14 09:47:16] [INFO] 【数据源3】国家博物馆官网
9
+[2026-07-14 09:47:16] [INFO] 国家博物馆提取:0 个展览
10
+[2026-07-14 09:47:17] [INFO] 【数据源4】携程展览汇总
11
+[2026-07-14 09:47:19] [INFO] 携程提取:27 个展览
12
+[2026-07-14 09:47:19] [INFO] 各源合计:27 条,去重后:27 条
13
+[2026-07-14 09:47:19] [INFO] 本地宝:0 | 美术馆:0 | 国博:0 | 携程:27
14
+[2026-07-14 09:47:19] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(27 个展览)
15
+[2026-07-14 09:47:19] [INFO] 完成!共 27 个展览
16
+[2026-07-14 09:47:19] [INFO] ============================================================
17
+[2026-07-14 09:49:13] [INFO] ============================================================
18
+[2026-07-14 09:49:13] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
19
+[2026-07-14 09:49:13] [INFO] ============================================================
20
+[2026-07-14 09:49:13] [INFO] 【数据源1】北京本地宝展览汇总
21
+[2026-07-14 09:49:14] [INFO] 本地宝[综合汇总]:4 个展览
22
+[2026-07-14 09:49:15] [INFO] 本地宝合计:4 个展览
23
+[2026-07-14 09:49:15] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
24
+[2026-07-14 09:49:15] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
25
+[2026-07-14 09:49:15] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
26
+[2026-07-14 09:49:15] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
27
+[2026-07-14 09:49:17] [INFO] 【数据源2】携程展览汇总
28
+[2026-07-14 09:49:18] [INFO] 携程提取:28 个展览
29
+[2026-07-14 09:49:18] [INFO] 合计:32 条,去重后:30 条
30
+[2026-07-14 09:49:18] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(30 个展览)
31
+[2026-07-14 09:49:18] [INFO] 完成!共 30 个展览
32
+[2026-07-14 09:50:06] [INFO] ============================================================
33
+[2026-07-14 09:50:06] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
34
+[2026-07-14 09:50:06] [INFO] ============================================================
35
+[2026-07-14 09:50:06] [INFO] 【数据源1】北京本地宝展览汇总
36
+[2026-07-14 09:50:07] [INFO] 本地宝[综合汇总]:4 个展览
37
+[2026-07-14 09:50:08] [INFO] 本地宝合计:4 个展览
38
+[2026-07-14 09:50:08] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
39
+[2026-07-14 09:50:08] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
40
+[2026-07-14 09:50:08] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
41
+[2026-07-14 09:50:08] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
42
+[2026-07-14 09:50:10] [INFO] 【数据源2】携程展览汇总
43
+[2026-07-14 09:50:12] [INFO] 携程提取:28 个展览
44
+[2026-07-14 09:50:12] [INFO] 合计:32 条,去重后:30 条
45
+[2026-07-14 09:50:12] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(30 个展览)
46
+[2026-07-14 09:50:12] [INFO] 完成!共 30 个展览
47
+[2026-07-14 09:52:09] [INFO] ============================================================
48
+[2026-07-14 09:52:09] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
49
+[2026-07-14 09:52:09] [INFO] ============================================================
50
+[2026-07-14 09:52:09] [INFO] 【数据源1】北京本地宝展览汇总
51
+[2026-07-14 09:52:09] [INFO] 本地宝[综合汇总]:4 个展览
52
+[2026-07-14 09:52:10] [INFO] 本地宝合计:4 个展览
53
+[2026-07-14 09:52:10] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
54
+[2026-07-14 09:52:10] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
55
+[2026-07-14 09:52:10] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
56
+[2026-07-14 09:52:10] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
57
+[2026-07-14 09:52:12] [INFO] 【数据源2】携程展览汇总
58
+[2026-07-14 09:52:14] [INFO] 携程提取:28 个展览
59
+[2026-07-14 09:52:14] [INFO] 合计:32 条,去重后:30 条
60
+[2026-07-14 09:52:14] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(30 个展览)
61
+[2026-07-14 09:52:14] [INFO] 完成!共 30 个展览
62
+[2026-07-14 09:53:02] [INFO] ============================================================
63
+[2026-07-14 09:53:02] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
64
+[2026-07-14 09:53:02] [INFO] ============================================================
65
+[2026-07-14 09:53:02] [INFO] 【数据源1】北京本地宝展览汇总
66
+[2026-07-14 09:53:03] [INFO] 本地宝[综合汇总]:6 个展览
67
+[2026-07-14 09:53:04] [INFO] 本地宝合计:6 个展览
68
+[2026-07-14 09:53:04] [INFO] -> 看·见——中国国家博物馆藏海外中国图像展 | 国家博物馆
69
+[2026-07-14 09:53:04] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
70
+[2026-07-14 09:53:04] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
71
+[2026-07-14 09:53:04] [INFO] -> 看·见——中国国家博物馆藏海外中国图像展 | 国家博物馆
72
+[2026-07-14 09:53:04] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
73
+[2026-07-14 09:53:04] [INFO] ... 等共 6 个
74
+[2026-07-14 09:53:06] [INFO] 【数据源2】携程展览汇总
75
+[2026-07-14 09:53:07] [INFO] 携程提取:28 个展览
76
+[2026-07-14 09:53:07] [INFO] 合计:34 条,去重后:31 条
77
+[2026-07-14 09:53:07] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(31 个展览)
78
+[2026-07-14 09:53:07] [INFO] 完成!共 31 个展览
79
+[2026-07-14 09:54:59] [INFO] ============================================================
80
+[2026-07-14 09:54:59] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
81
+[2026-07-14 09:54:59] [INFO] ============================================================
82
+[2026-07-14 09:54:59] [INFO] 【数据源1】北京本地宝展览汇总
83
+[2026-07-14 09:55:00] [INFO] 本地宝[P1]:6 个展览
84
+[2026-07-14 09:55:01] [INFO] 本地宝[P2]:0 个展览
85
+[2026-07-14 09:55:02] [INFO] 本地宝[P3]:0 个展览
86
+[2026-07-14 09:55:03] [INFO] 本地宝[P4]:0 个展览
87
+[2026-07-14 09:55:04] [INFO] 本地宝[P5]:0 个展览
88
+[2026-07-14 09:55:05] [INFO] 本地宝[P6]:2 个展览
89
+[2026-07-14 09:55:06] [INFO] 本地宝[P7]:0 个展览
90
+[2026-07-14 09:55:08] [INFO] 本地宝[P8]:6 个展览
91
+[2026-07-14 09:55:12] [INFO] 本地宝[P9]:2 个展览
92
+[2026-07-14 09:55:14] [INFO] 本地宝[P10]:0 个展览
93
+[2026-07-14 09:55:15] [INFO] 本地宝[P11]:0 个展览
94
+[2026-07-14 09:55:16] [INFO] 本地宝[P12]:0 个展览
95
+[2026-07-14 09:55:17] [INFO] 本地宝[P13]:6 个展览
96
+[2026-07-14 09:55:18] [INFO] 本地宝[P14]:4 个展览
97
+[2026-07-14 09:55:19] [INFO] 本地宝[P15]:4 个展览
98
+[2026-07-14 09:55:20] [INFO] 本地宝[P16]:0 个展览
99
+[2026-07-14 09:55:22] [INFO] 本地宝[P17]:4 个展览
100
+[2026-07-14 09:55:23] [INFO] 本地宝[P18]:0 个展览
101
+[2026-07-14 09:55:24] [INFO] 本地宝[P19]:0 个展览
102
+[2026-07-14 09:55:25] [INFO] 本地宝[P20]:0 个展览
103
+[2026-07-14 09:55:26] [INFO] 本地宝[P21]:0 个展览
104
+[2026-07-14 09:55:27] [INFO] 本地宝[P22]:0 个展览
105
+[2026-07-14 09:55:29] [INFO] 本地宝[P23]:0 个展览
106
+[2026-07-14 09:55:30] [INFO] 本地宝合计:34 个展览
107
+[2026-07-14 09:55:30] [INFO] -> 看·见——中国国家博物馆藏海外中国图像展 | 国家博物馆
108
+[2026-07-14 09:55:30] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
109
+[2026-07-14 09:55:30] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
110
+[2026-07-14 09:55:30] [INFO] -> 看·见——中国国家博物馆藏海外中国图像展 | 国家博物馆
111
+[2026-07-14 09:55:30] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
112
+[2026-07-14 09:55:30] [INFO] ... 等共 34 个
113
+[2026-07-14 09:55:32] [INFO] 【数据源2】携程展览汇总
114
+[2026-07-14 09:55:37] [INFO] 携程提取:0 个展览
115
+[2026-07-14 09:55:37] [INFO] 合计:34 条,去重后:17 条
116
+[2026-07-14 09:55:37] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(17 个展览)
117
+[2026-07-14 09:55:37] [INFO] 完成!共 17 个展览
118
+[2026-07-14 09:56:59] [INFO] ============================================================
119
+[2026-07-14 09:56:59] [INFO] 北京展览爬取 v3(多源直接抓取)- 2026-07-14
120
+[2026-07-14 09:56:59] [INFO] ============================================================
121
+[2026-07-14 09:56:59] [INFO] 【数据源1】北京本地宝展览汇总
122
+[2026-07-14 09:56:59] [INFO] 本地宝[P1]:6 个展览
123
+[2026-07-14 09:57:00] [INFO] 本地宝[P2]:0 个展览
124
+[2026-07-14 09:57:01] [INFO] 本地宝[P3]:0 个展览
125
+[2026-07-14 09:57:02] [INFO] 本地宝[P4]:0 个展览
126
+[2026-07-14 09:57:04] [INFO] 本地宝[P5]:0 个展览
127
+[2026-07-14 09:57:05] [INFO] 本地宝[P6]:2 个展览
128
+[2026-07-14 09:57:06] [INFO] 本地宝[P7]:0 个展览
129
+[2026-07-14 09:57:07] [INFO] 本地宝[P8]:6 个展览
130
+[2026-07-14 09:57:08] [INFO] 本地宝[P9]:2 个展览
131
+[2026-07-14 09:57:09] [INFO] 本地宝[P10]:0 个展览
132
+[2026-07-14 09:57:10] [INFO] 本地宝[P11]:0 个展览
133
+[2026-07-14 09:57:12] [INFO] 本地宝[P12]:0 个展览
134
+[2026-07-14 09:57:13] [INFO] 本地宝[P13]:6 个展览
135
+[2026-07-14 09:57:14] [INFO] 本地宝[P14]:4 个展览
136
+[2026-07-14 09:57:15] [INFO] 本地宝[P15]:4 个展览
137
+[2026-07-14 09:57:16] [INFO] 本地宝[P16]:0 个展览
138
+[2026-07-14 09:57:17] [INFO] 本地宝[P17]:4 个展览
139
+[2026-07-14 09:57:18] [INFO] 本地宝[P18]:0 个展览
140
+[2026-07-14 09:57:20] [INFO] 本地宝[P19]:0 个展览
141
+[2026-07-14 09:57:21] [INFO] 本地宝[P20]:0 个展览
142
+[2026-07-14 09:57:22] [INFO] 本地宝[P21]:0 个展览
143
+[2026-07-14 09:57:23] [INFO] 本地宝[P22]:0 个展览
144
+[2026-07-14 09:57:24] [INFO] 本地宝[P23]:0 个展览
145
+[2026-07-14 09:57:25] [INFO] 本地宝合计:34 个展览
146
+[2026-07-14 09:57:25] [INFO] -> 看·见——中国国家博物馆藏海外中国图像展 | 国家博物馆
147
+[2026-07-14 09:57:25] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
148
+[2026-07-14 09:57:25] [INFO] -> 巴西魂——波尔蒂纳里艺术展 | 国家博物馆
149
+[2026-07-14 09:57:25] [INFO] -> 看·见——中国国家博物馆藏海外中国图像展 | 国家博物馆
150
+[2026-07-14 09:57:25] [INFO] -> 行·迹——卡塔尔游牧生活与文化展 | 国家博物馆
151
+[2026-07-14 09:57:25] [INFO] ... 等共 34 个
152
+[2026-07-14 09:57:27] [INFO] 【数据源2】携程展览汇总
153
+[2026-07-14 09:57:29] [INFO] 携程提取:0 个展览
154
+[2026-07-14 09:57:29] [INFO] 合计:34 条,去重后:17 条
155
+[2026-07-14 09:57:29] [INFO] 报告已生成:/root/.openclaw/workspace/travel/beijing-exhibitions/scripts/data/beijing_exhibitions_2026-07-14.md(17 个展览)
156
+[2026-07-14 09:57:29] [INFO] 完成!共 17 个展览
beijing-exhibitions/scripts/logs/exhibition_20260714.log
... ...
@@ -0,0 +1,15 @@
1
+[2026-07-14 09:00:02] [INFO] ============================================================
2
+[2026-07-14 09:00:02] [INFO] 北京展览爬取(优先北京市文物局)
3
+[2026-07-14 09:00:02] [INFO] ============================================================
4
+[2026-07-14 09:00:02] [INFO] 数据库初始化完成
5
+[2026-07-14 09:00:02] [INFO]
6
+【1】北京市文物局 ⭐⭐⭐⭐⭐
7
+[2026-07-14 09:00:04] [INFO] 获取 2 个
8
+[2026-07-14 09:00:04] [INFO]
9
+【2】各大博物馆 ⭐⭐⭐⭐
10
+[2026-07-14 09:00:14] [INFO]
11
+【3】聚合信息 ⭐⭐⭐
12
+[2026-07-14 09:00:16] [INFO] 去重后:20 个
13
+[2026-07-14 09:00:16] [INFO] 对比:新增18个,移除3个
14
+[2026-07-14 09:00:16] [INFO] ============================================================
15
+[2026-07-14 09:00:16] [INFO] 完成!20 个展览,新增18个,移除3个
memory/2026-07-14.md
... ...
@@ -60,3 +60,19 @@
60 60
61 61
*创建时间:2026-07-14 00:00:01*
62 62
*维护者:Travel Agent*
63
+
64
+---
65
+
66
+## ✅ 自动任务记录 - 北京展览爬取
67
+
68
+**时间**:2026-07-14 09:00:02
69
+**状态**:成功
70
+**数据源**:北京市文物局 + 豆瓣同城 + 中国美术馆
71
+**展览数量**:20 个
72
+**飞书文档**:https://feishu.cn/docx/AvQIdVgKSoMHB5xhzkUcRKZzn8f
73
+
74
+**三层记忆检查**:
75
+- [x] 第 1 层:今日记忆已更新
76
+- [ ] 第 2 层:Session 开始前读取记忆(手动)
77
+- [ ] 第 3 层:高风险操作前检查约束(按需)
78
+