Files
hbr-crawler/AI爬蟲設計.txt
DonaldFang 方士碩 f524713cb6 Initial commit: HBR 文章爬蟲專案
- Scrapy 爬蟲框架,爬取 HBR 繁體中文文章
- Flask Web 應用程式,提供文章查詢介面
- SQL Server 資料庫整合
- 自動化排程與郵件通知功能

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 17:19:56 +08:00

142 lines
4.5 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

一、結論(可直接採用)
排程時間:每週一 08:00 Asia/Taipei。
流程scrapy crawl hbr 產出 hbr_articles.csv → 以 Gmail SMTP 寄出(需 App Password
寄信對象kaeruzak@gmail.com主旨含日期附檔 hbr_articles.csv。
GitHub Actions免自備機器建議做法
下方已提供寄信腳本 send_mail.py 與兩種排程設定檔,照貼即可運作。
二、寄信腳本(共用)
檔名send_mail.py放在專案根目錄與 hbr_articles.csv 同層或以參數指定路徑)
# send_mail.py
import os, smtplib, sys, mimetypes
from datetime import datetime, timezone, timedelta
from email.message import EmailMessage
# 讀環境變數(請在 crontab 或 GitHub Actions secrets 設定)
GMAIL_USER = os.environ.get("GMAIL_USERNAME") # 例如yourname@gmail.com
GMAIL_PASS = os.environ.get("GMAIL_APP_PASSWORD") # 16碼 App Password非一般登入密碼
TO = os.environ.get("MAIL_TO", "kaeruzak@gmail.com")
# 參數CSV 路徑(預設 ./hbr_articles.csv
csv_path = sys.argv[1] if len(sys.argv) > 1 else "hbr_articles.csv"
if not os.path.exists(csv_path):
print(f"[WARN] CSV not found: {csv_path}")
# 可選:直接結束或改為寄送「今日無檔案」通知
sys.exit(0)
# 產生台北時間日期字串
tz = timezone(timedelta(hours=8))
date_str = datetime.now(tz).strftime("%Y-%m-%d %H:%M")
# 組信
msg = EmailMessage()
msg["Subject"] = f"[HBRTW 每週爬取] 文章清單 CSV - {date_str}"
msg["From"] = GMAIL_USER
msg["To"] = TO
msg.set_content(f"""您好,
附件為本週 HBR Taiwan 最新/熱門文章彙整CSV
產生時間:{date_str}Asia/Taipei
若您需要改排程或加上上傳雲端,回覆此信即可。
""")
# 夾帶 CSV
ctype, encoding = mimetypes.guess_type(csv_path)
if ctype is None or encoding is not None:
ctype = "application/octet-stream"
maintype, subtype = ctype.split("/", 1)
with open(csv_path, "rb") as f:
msg.add_attachment(f.read(),
maintype=maintype,
subtype=subtype,
filename=os.path.basename(csv_path))
# 寄送
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as smtp:
smtp.login(GMAIL_USER, GMAIL_PASS)
smtp.send_message(msg)
print("[OK] Mail sent to", TO)
安全性:請使用 Gmail App Password兩步驟驗證後生成不要用一般密碼。
取得方式Google 帳戶 → 安全性 → 兩步驟驗證 → App 密碼 → 選「郵件」、裝置隨意命名 → 取得 16 碼,填入下述 Secrets/環境變數。
四、方案 BGitHub Actions建議
在 GitHub 專案的 Settings → Secrets and variables → Actions → New repository secret 新增:
GMAIL_USERNAME您的 Gmail 地址
GMAIL_APP_PASSWORD16 碼 App Password
MAIL_TOkaeruzak@gmail.com
建立 .github/workflows/weekly.yml
name: weekly-crawl
on:
schedule:
- cron: "0 0 * * 1" # 週一 00:00 UTC ≈ 台北 08:00
workflow_dispatch: {}
jobs:
crawl-and-mail:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- run: pip install scrapy
- name: Run crawler
run: scrapy crawl hbr
- name: Send mail with CSV
env:
GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
GMAIL_APP_PASSWORD: ${{ secrets.GMAIL_APP_PASSWORD }}
MAIL_TO: ${{ secrets.MAIL_TO }}
run: |
python send_mail.py hbr_articles.csv
- name: Upload CSV as artifact (optional)
uses: actions/upload-artifact@v4
with:
name: hbr_articles_csv
path: hbr_articles.csv
優點免維護伺服器Secrets 隔離;失敗可在 Actions 介面看 Log。
五、快速驗證(手動)
在本機或任一環境先手動測一次:
# 1) 先跑爬蟲
scrapy crawl hbr
# 2) 設定環境變數(僅當前終端有效)
export GMAIL_USERNAME='yourname@gmail.com'
export GMAIL_APP_PASSWORD='xxxxxxxxxxxxxxxx'
export MAIL_TO='kaeruzak@gmail.com'
# 3) 寄信
python send_mail.py hbr_articles.csv
若收得到信,表示排程也會正常。
六、例外與健壯性建議
robots.txt/付費牆:既有設定已遵守;付費文章僅做 is_paywalled=1 標記,不抓內文。
站台改版:若有解析錯誤,優先檢查 spiders/hbr.py 中 CSS 選擇器。
空結果週:預設若找不到 CSV 會跳過寄信(可改為寄送「本週無新檔案」通知)。
多環境如需同時上傳雲端S3/Drive或加 Slack/Teams 通知,可再加一步。