01 基本資訊 #
幾個重點參數,搞懂這段就能開始介接。
| Base URL | https://317767.com/api_public.php |
| 認證方式 | Query string ?token=xxx 或 HTTP header X-API-Token: xxx |
| 取得 Token | 請聯絡站長(不在公開頁面提供,避免被爬) |
| Rate limit | 每個 endpoint + IP 60 秒 1 次(4 個 endpoint 獨立鎖) |
| Cache | server-side 5 分鐘(query 變化 = 不同 cache,部署新版自動失效) |
| CORS | Access-Control-Allow-Origin: *(browser fetch OK) |
| 編碼 | UTF-8 |
| 時區 | 所有時間欄位都是 UTC(pub_date / updated_at) |
02 認證方式 #
兩種方式帶 token,二選一就好。
每個 token 對一家合作方,可在後台 🔑 API Tokens 頁面管理(建立 / 設配額 / 停用 / 重新生成 / 刪除)。
03 統一 Response 格式 #
所有 endpoint 都回這格式(成功/失敗都一樣)。
成功
"ok": true,
"data": { /* 各 endpoint 不同 */ },
"_meta": {
"cached": false,
"cache_age_sec": 0
}失敗
"ok": false,
"error": "bad_endpoint",
"message": "未知 endpoint: ''",
"hint": "endpoint=sync|categories|article|stats"_meta.cached = true
表示從 server-side 5 分鐘 cache 回的(沒打 DB)。cache_age_sec 是 cache 已存在秒數。
04 4 個 Endpoint #
每個 endpoint 一張卡片,要哪個用哪個。
Query 參數
| 參數 | 必填 | 說明 |
|---|---|---|
since | 選填 | ISO8601(如 2026-07-30T00:00:00Z)或 unix timestamp。不傳 = 預設回 7 天內 |
lookback_days | 選填 | 限制 since 最大回溯天數(1-30,預設 7)。超過會被自動 clamp。舊新聞不提供,建議設小一點省流量。 |
limit | 選填 | 單次回傳筆數上限,預設 100, max 500。用 has_more + next_since 分批拿 |
region | 選填 | 篩單一地區:tw / hk / jp / us / intl |
chip | 選填 | 篩單一 chip(要搭配 region) |
本 API 只保留最近 30 天的新聞資料(v5.5.1 防拉爆機制)。超過 30 天的舊新聞不在範圍內,since 設太舊會被自動 clamp 到 30 天前。
對應你的 DB 也會定期清掉 90 天前的舊新聞(給 SEO / 內部搜尋保留更久,外部 API 只給 30 天)。
範例 URL
# 拿 2026-07-30 18:00 之後變動的新聞,最多 200 篇
GET /api_public.php?endpoint=sync&token=YOUR_TOKEN&since=2026-07-30T18:00:00Z&limit=200
# 拿台灣地區最近 3 天內的
GET /api_public.php?endpoint=sync&token=YOUR_TOKEN®ion=tw&lookback_days=3&limit=3
# 不帶 since:自動回 7 天內全部(首次 sync 用)
GET /api_public.php?endpoint=sync&token=YOUR_TOKEN&limit=500回傳 JSON
{
"ok": true,
"data": {
"items": [
{
"id": 1234,
"title": "標題",
"url": "https://tw.news.yahoo.com/...",
"image": "https://...",
"source": "tw.news.yahoo.com",
"content": "純文字摘要(最多 500 字)...",
"content_full_len": 1842,
"region": "tw",
"chip": "headline",
"pub_date": "2026-07-30T10:00:00+00:00",
"pub_date_ts": 1722333600,
"updated_at": "2026-07-30T18:30:00+00:00",
"updated_at_ts": 1722364200
}
],
"count": 87,
"has_more": false,
"next_since": "2026-07-30T18:30:00+00:00",
"since_used": "2026-07-30T18:00:00+00:00",
"filter": { "region": null, "chip": null, "limit": 200 }
}
}url 當主鍵(RSS source URL 唯一不重複,不會變)
updated_at 當 sync 游標(不是 pub_date — 抓新增 + 修改)
同 URL 但內容變 → 你的 UPSERT 要更新所有欄位
has_more: true → 把 next_since 當下次 since 再打
content_full_len > 500 → 想拿全文打 article 端點
範例
GET /api_public.php?endpoint=categories&token=YOUR_TOKEN回傳摘要
回傳 data.regions(5 個地區)+ data.region_labels(中文標籤)+ data.chips(每地區下的 chip 列表含 chip / label / count)。
Query 參數
| 參數 | 必填 | 說明 |
|---|---|---|
id | ✓ | 從 sync 拿的 items[].id |
範例
GET /api_public.php?endpoint=article&token=YOUR_TOKEN&id=1234回傳 data.content 是完整純文字(無長度限制)。
last_ingest.failed > 0 表示要關心。範例
GET /api_public.php?endpoint=stats&token=YOUR_TOKEN回傳 total_news / total_published / by_region / last_ingest(含 started_at / finished_at / inserted / updated / failed)。
05 錯誤碼 #
6 種錯誤情境,全部回 JSON(前端可解析)。
| HTTP | error | 原因 |
|---|---|---|
| 400 | bad_endpoint | 沒帶 endpoint 或值不在 sync/categories/article/stats |
| 400 | bad_id | article 端點沒帶 id |
| 403 | forbidden | 沒帶 token / token 錯 / 過期 / 已停用 |
| 404 | not_found | article 端點 id 找不到或未上架 |
| 429 | rate_limited | 60s 內重複打同 endpoint,請等 message 裡的秒數 |
| 429 | quota_exceeded | 每日配額已用完(含 limit + reset_at 提示明天重置) |
| 500 | internal | DB 連線失敗或 query 出包,看 message |
06 Rate / Cache / CORS 細節 #
- Rate limit:60 秒 1 次 per endpoint per IP。每個 endpoint 獨立鎖,互不影響。30 分鐘 cron 跑 sync 絕對夠用。
- Cache:server-side 5 分鐘 file cache。同一 query 5 分鐘內重複打 → server 不打 DB。cache key 綁 server 檔案 mtime,部署新版後自動失效。
- CORS:
Access-Control-Allow-Origin: *,Access-Control-Allow-Headers: X-API-Token, Content-Type,browser fetch OK。 - 時區:所有
*_date跟*_ts欄位都是 UTC(*_dateISO8601 with+00:00,*_tsunix timestamp)。 - 資料範圍(v5.5.1):
sync端點只保留最近 30 天,since設太舊會被 clamp。預設lookback_days=7,可設 1-30。
07 完整 Python 範例 #
差量 sync + 30 分鐘 cron,直接貼上跑。
import requests
import json
TOKEN = "YOUR_TOKEN" # 跟站長要
API = "https://317767.com/api_public.php"
def sync_news(last_sync=None):
"""差量同步,回傳新的 last_sync 給下次用"""
params = {"endpoint": "sync", "token": TOKEN, "limit": 500}
if last_sync:
params["since"] = last_sync
while True:
r = requests.get(API, params=params).json()
if not r["ok"]:
raise Exception(f"API error: {r}")
for item in r["data"]["items"]:
# URL 當主鍵,UPSERT 到你的 DB
db.upsert("news", item) # 改的話就 update,新就 insert
if not r["data"]["has_more"]:
return r["data"]["next_since"]
# 推進游標繼續拿
params["since"] = r["data"]["next_since"]
# cron 每 30 分鐘跑一次(跟我 ingest 同步率一致)
last_sync = load_last_sync() # 從你的 DB 或 file 讀上次 sync 時間
new_sync = sync_news(last_sync)
save_last_sync(new_sync)🤖 給 AI 的快速摘要
- Base URL:
https://317767.com/api_public.php - 認證:
?token=YOUR_TOKENquery 或X-API-Token: YOUR_TOKENheader - 4 個 endpoint:
sync(差量)/categories(分類導航)/article(單篇全文)/stats(監控) - Response 統一:
{ok, data, _meta: {cached, cache_age_sec}} - sync 設計:
updated_at篩選(不是pub_date),URL 當主鍵,has_more+next_since分頁 - 建議 30 分鐘 cron sync 一次(對方 DB 鏡像寫,本機 0 負擔)
- Rate limit: 60s per endpoint per IP;CORS 開放;server-side 5 分鐘 cache
- 資料範圍:sync 只回最近 30 天(
lookback_days預設 7,max 30),舊新聞不提供