算起來語雀也經營了不算短的時間,去年服務器宕機加之玉伯離開是棄絕該平台的直接原因,但根本上,還是因為意識到這個平台骨子裡是封閉的,自我審查到變態程度,更極難自己對接到主流的AI上;最近還發現又多了一個特定IP不能訪問的毛病。去年一年基本沒動,前年課程數據也都擱置在內僅懷舊。
新學期,論壇整理完畢,順手清理之前數據到語雀。看了下,語雀官方去年底更新了API獲取文檔的說明:https://www.yuque.com/yuque/developer/gyht993a76zg54mv。仅旗舰版空间可使用,還故意僅寫一個思路,基本就是直白地在說,我不想你往外導數據。唉,開放點,就那麼難嗎⋯⋯
好吧,核心的課程數據也就在一個團隊,自己遷出自己,夠了。
客觀上,雖然是以團隊而非空間為導出單位,畢竟,可以一個個團隊導出所有數據,這就意味著,真有要遷移一個整體空間的要求時,收集到全部團隊API,做好時間間隔設置,是可以整體搬家的。當然,因為噁心的 獨有lakebook,導出的json最多就是存檔,幾乎是不可直接對接別家的。
這就很完美閉環,因為封閉,所以封閉;當初超星家的PDG都沒你噁心。
I generated an image with the prompt: 'farewell image for a platform called Yuque, depicting its closed nature'.--By Grok
清理完本輪,算真的再見了。
import requests import os import re from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry API_TOKEN = '' BASE_URL = 'https://www.yuque.com/api/v2' TEAM_NAMESPACE = 'qrvbic' headers = { 'X-Auth-Token': API_TOKEN } # 設置重試策略 retry_strategy = Retry( total=5, # 重試次數 backoff_factor=1, # 重試間隔時間 status_forcelist=[429, 500, 502, 503, 504], # 會觸發重試的 HTTP 狀態碼 allowed_methods=["HEAD", "GET", "OPTIONS"] # 適用於重試的 HTTP 方法 ) adapter = HTTPAdapter(max_retries=retry_strategy) http = requests.Session() http.mount("https://", adapter) # 創建存放導出文件的文件夾 if not os.path.exists(TEAM_NAMESPACE): os.makedirs(TEAM_NAMESPACE) # 獲取團隊中的所有 repository def get_repos(team_namespace): url = f'{BASE_URL}/groups/{team_namespace}/repos' try: response = http.get(url, headers=headers, verify=False) response.raise_for_status() except requests.exceptions.RequestException as e: print(f"Error fetching repositories: {e}") return [] return response.json() # 獲取每個 repository 中的文檔 def get_docs(repo_id): url = f'{BASE_URL}/repos/{repo_id}/docs' try: response = http.get(url, headers=headers, verify=False) response.raise_for_status() except requests.exceptions.RequestException as e: print(f"Error fetching documents: {e}") return [] return response.json() # 將文檔導出為 Markdown 格式 def export_doc(repo_id, doc_id, title): url = f'{BASE_URL}/repos/{repo_id}/docs/{doc_id}?raw=1' try: response = http.get(url, headers=headers, verify=False) response.raise_for_status() except requests.exceptions.RequestException as e: print(f"Error exporting document '{title}': {e}") return # 處理文件名中的非法字符 safe_title = re.sub(r'[\/:*?"<>|]', '_', title) # 創建 repository 對應的文件夾 repo_dir = os.path.join(TEAM_NAMESPACE, str(repo_id)) if not os.path.exists(repo_dir): os.makedirs(repo_dir) # 將文檔保存為 Markdown 文件 file_path = os.path.join(repo_dir, f"{safe_title}.md") with open(file_path, "w") as f: f.write(response.text) # 主邏輯 if __name__ == '__main__': # 獲取團隊下的所有 repository repos = get_repos(TEAM_NAMESPACE) if repos: # 遍歷每個 repository for repo in repos['data']: repo_id = repo['id'] repo_name = repo['name'] print(f"正在導出 repository: {repo_name}") # 獲取該 repository 下的所有文檔 docs = get_docs(repo_id) # 導出每個文檔 if docs: for doc in docs['data']: title = doc['title'] doc_id = doc['id'] print(f" 導出文檔: {title}") export_doc(repo_id, doc_id, title) print("導出完成!")
Comments
Post a Comment