khjhs60199 commited on
Commit
100c661
·
verified ·
1 Parent(s): f8e4847

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +188 -3
app.py CHANGED
@@ -450,8 +450,193 @@ def api_get_progress():
450
 
451
  # 創建 Gradio 介面
452
  def create_interface():
453
- # ... (Gradio 介面代碼保持不變)
454
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
 
456
  # 啟動應用
457
  if __name__ == "__main__":
@@ -469,7 +654,7 @@ if __name__ == "__main__":
469
  print("⚡ 自動功能: 系統啟動後自動檢測並爬取新聞")
470
 
471
  # 啟動Gradio介面
472
- interface = create_interface()
473
  interface.launch(
474
  server_name="0.0.0.0",
475
  server_port=7860,
 
450
 
451
  # 創建 Gradio 介面
452
  def create_interface():
453
+ with gr.Blocks(
454
+ title="📈 股市新聞情緒分析器",
455
+ theme=gr.themes.Soft(),
456
+ css="""
457
+ .news-positive { background: linear-gradient(90deg, #d4edda 0%, #c3e6cb 100%); border-left: 4px solid #28a745; }
458
+ .news-negative { background: linear-gradient(90deg, #f8d7da 0%, #f5c6cb 100%); border-left: 4px solid #dc3545; }
459
+ .news-neutral { background: linear-gradient(90deg, #e2e3e5 0%, #d6d8db 100%); border-left: 4px solid #6c757d; }
460
+ .news-card { margin: 10px 0; padding: 15px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
461
+ .sentiment-badge { padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: bold; }
462
+ .positive-badge { background: #28a745; color: white; }
463
+ .negative-badge { background: #dc3545; color: white; }
464
+ .neutral-badge { background: #6c757d; color: white; }
465
+ .progress-box { background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 5px; padding: 10px; font-family: monospace; font-size: 14px; }
466
+ """
467
+ ) as interface:
468
+
469
+ gr.Markdown("""
470
+ # 📈 股市新聞情緒分析器 - 自動版
471
+
472
+ 🤖 自動爬取鉅亨網美股和台股新聞,並進行即時中文情緒分析
473
+
474
+ ⚡ **自動啟動**: 程式啟動後自動開始爬取新聞
475
+ 🎯 **智能分析**: 使用 RoBERTa 模型進行情緒分析
476
+ 🔍 **多條件篩選**: 支援時間段、關鍵字、情緒篩選
477
+ 📊 **即時統計**: 提供詳細的新聞統計資訊
478
+ """)
479
+
480
+ with gr.Tab("📰 最新新聞"):
481
+ with gr.Row():
482
+ with gr.Column(scale=1):
483
+ category_radio = gr.Radio(
484
+ choices=[
485
+ ("所有新聞", "all"),
486
+ ("美股新聞", "us_stock"),
487
+ ("台股新聞", "tw_stock")
488
+ ],
489
+ value="all",
490
+ label="📋 新聞分類"
491
+ )
492
+
493
+ days_slider = gr.Slider(
494
+ minimum=0,
495
+ maximum=30,
496
+ value=7,
497
+ step=1,
498
+ label="📅 時間範圍 (天)",
499
+ info="0表示不限制時間"
500
+ )
501
+
502
+ keyword_input = gr.Textbox(
503
+ label="🔍 關鍵字搜尋",
504
+ placeholder="輸入關鍵字搜尋新聞...",
505
+ value=""
506
+ )
507
+
508
+ sentiment_radio = gr.Radio(
509
+ choices=[
510
+ ("所有情緒", "all"),
511
+ ("正面情緒", "positive"),
512
+ ("負面情緒", "negative"),
513
+ ("中性情緒", "neutral")
514
+ ],
515
+ value="all",
516
+ label="😊 情緒篩選"
517
+ )
518
+
519
+ # 爬蟲模式選擇
520
+ crawl_mode = gr.Radio(
521
+ choices=[
522
+ ("無限制爬取 (全部文章)", True),
523
+ ("限制爬取 (20篇)", False)
524
+ ],
525
+ value=True,
526
+ label="🚀 爬蟲模式",
527
+ info="選擇爬取模式"
528
+ )
529
+
530
+ with gr.Column(scale=2):
531
+ with gr.Row():
532
+ search_btn = gr.Button("🔍 搜尋新聞", variant="primary")
533
+ refresh_btn = gr.Button("🔄 重新整理", variant="secondary")
534
+ manual_crawl_btn = gr.Button("🚀 手動爬取", variant="secondary")
535
+
536
+ # 進度顯示
537
+ progress_display = gr.Textbox(
538
+ label="📊 系統狀態",
539
+ value=app.current_progress,
540
+ interactive=False,
541
+ elem_classes=["progress-box"],
542
+ lines=1
543
+ )
544
+
545
+ news_display = gr.HTML(
546
+ label="新聞內容",
547
+ value="⏳ 系統正在初始化並自動爬取新聞,請稍候..."
548
+ )
549
+ crawl_result = gr.Textbox(label="爬取結果", visible=False)
550
+
551
+ # 更新函數
552
+ def update_progress_only():
553
+ """只更新進度,不更新新聞"""
554
+ progress, needs_update = app.get_progress()
555
+ if needs_update or app.is_crawling:
556
+ return progress
557
+ else:
558
+ return gr.update()
559
+
560
+ def update_news_automatically():
561
+ """自動更新新聞內容"""
562
+ if app.auto_crawl_completed:
563
+ return app.get_latest_news("all", 7, "", "all", force_refresh=True)
564
+ else:
565
+ return gr.update()
566
+
567
+ def search_news(category, days, keyword, sentiment):
568
+ """搜尋新聞"""
569
+ logger.info(f"搜尋新聞 - 分類: {category}, 天數: {days}, 關鍵字: '{keyword}', 情緒: {sentiment}")
570
+ return app.get_latest_news(category, days, keyword, sentiment, force_refresh=True)
571
+
572
+ def refresh_current_search(category, days, keyword, sentiment):
573
+ """刷新當前搜尋"""
574
+ return app.get_latest_news(category, days, keyword, sentiment, force_refresh=True)
575
+
576
+ def handle_manual_crawl(category, days, keyword, sentiment, unlimited_mode):
577
+ """處理手動爬蟲"""
578
+ result = app.manual_crawl(unlimited=unlimited_mode)
579
+ # 爬取完成後自動刷新當前搜尋
580
+ news = app.get_latest_news(category, days, keyword, sentiment, force_refresh=True)
581
+ return result, news
582
+
583
+ # 進度更新定時器
584
+ progress_timer = gr.Timer(value=10)
585
+ progress_timer.tick(
586
+ fn=update_progress_only,
587
+ outputs=[progress_display]
588
+ )
589
+
590
+ # 新聞自動更新定時器
591
+ news_timer = gr.Timer(value=15) # 每15秒檢查一次
592
+ news_timer.tick(
593
+ fn=update_news_automatically,
594
+ outputs=[news_display]
595
+ )
596
+
597
+ # 綁定事件
598
+ search_btn.click(
599
+ search_news,
600
+ inputs=[category_radio, days_slider, keyword_input, sentiment_radio],
601
+ outputs=[news_display]
602
+ )
603
+
604
+ refresh_btn.click(
605
+ refresh_current_search,
606
+ inputs=[category_radio, days_slider, keyword_input, sentiment_radio],
607
+ outputs=[news_display]
608
+ )
609
+
610
+ manual_crawl_btn.click(
611
+ handle_manual_crawl,
612
+ inputs=[category_radio, days_slider, keyword_input, sentiment_radio, crawl_mode],
613
+ outputs=[crawl_result, news_display]
614
+ ).then(
615
+ lambda: gr.update(visible=True),
616
+ outputs=[crawl_result]
617
+ )
618
+
619
+ # 分類改變時自動搜尋
620
+ category_radio.change(
621
+ search_news,
622
+ inputs=[category_radio, days_slider, keyword_input, sentiment_radio],
623
+ outputs=[news_display]
624
+ )
625
+
626
+ # 初始載入時顯示等待訊息
627
+ interface.load(
628
+ lambda: "⏳ 系統正在自動爬取新聞,請稍候...",
629
+ outputs=[news_display]
630
+ )
631
+
632
+ with gr.Tab("📊 統計資訊"):
633
+ stats_display = gr.Markdown()
634
+ stats_refresh_btn = gr.Button("🔄 更新統計")
635
+
636
+ stats_refresh_btn.click(app.get_statistics, outputs=[stats_display])
637
+ interface.load(app.get_statistics, outputs=[stats_display])
638
+
639
+ return interface # ⬅️ 這裡是關鍵!一定要返回 interface
640
 
641
  # 啟動應用
642
  if __name__ == "__main__":
 
654
  print("⚡ 自動功能: 系統啟動後自動檢測並爬取新聞")
655
 
656
  # 啟動Gradio介面
657
+ interface = create_interface() # 修正:正確獲取interface
658
  interface.launch(
659
  server_name="0.0.0.0",
660
  server_port=7860,