Python實(shí)現(xiàn)Excel數(shù)據(jù)同步到飛書文檔
一、整體目標(biāo)
核心功能:自動(dòng)將Excel數(shù)據(jù)同步到飛書文檔的末尾,并添加時(shí)間戳。
應(yīng)用場(chǎng)景:
- 每日銷售數(shù)據(jù)報(bào)表自動(dòng)更新到團(tuán)隊(duì)文檔
- 周報(bào)自動(dòng)化生成
- 實(shí)時(shí)數(shù)據(jù)看板同步
二、代碼結(jié)構(gòu)拆解
# 基礎(chǔ)設(shè)施層 import pandas as pd # 數(shù)據(jù)處理 import requests # 網(wǎng)絡(luò)請(qǐng)求 import logging # 錯(cuò)誤追蹤 from datetime import datetime # 時(shí)間處理 # 配置層 logging配置 → API密鑰配置 # 功能層 get_access_token() → 獲取系統(tǒng)通行證 insert_to_feishu() → 內(nèi)容插入邏輯 # 執(zhí)行層 main() → 流程控制器
三、核心邏輯講解(重點(diǎn))
用「快遞送貨」做類比:
1. 建立安全連接(獲取access_token)
好比:快遞員需要先獲取小區(qū)門禁卡
流程:
- 準(zhǔn)備身份證(APP_ID)和密碼(APP_SECRET)
- 到門衛(wèi)處(飛書認(rèn)證接口)驗(yàn)證身份
- 獲得臨時(shí)通行證(tenant_access_token)
response = requests.post(url, json=data) # 發(fā)送驗(yàn)證請(qǐng)求 return response.json()["tenant_access_token"] # 提取通行證
2. 定位文檔位置
好比:找到要送貨的樓層和房間
兩步作:
1.獲取整棟樓結(jié)構(gòu)(獲取文檔所有內(nèi)容塊)
blocks = requests.get(blocks_url).json()["data"]["items"]
2.找到最后一間房(定位最后一個(gè)內(nèi)容塊)
last_block_id = blocks[-1]["block_id"] # 列表末尾元素
3. 數(shù)據(jù)包裝與投遞
好比:打包貨物并送貨
包裝階段:
# 添加醒目時(shí)間標(biāo)簽 時(shí)間戳 = datetime.now().strftime(...) # 將Excel轉(zhuǎn)為Markdown表格 markdown_table = df.to_markdown(index=False)
投遞作:
requests.post(insert_url, json={ "content": "**時(shí)間標(biāo)簽** + 表格數(shù)據(jù)", "position": "after" # 放在最后 })
四、異常處理機(jī)制
用「行車記錄儀」做類比:
日志配置(相當(dāng)于安裝記錄儀)
logging.basicConfig( filename='feishu_sync.log', # 記錄文件 level=logging.INFO, # 記錄級(jí)別 format='時(shí)間-級(jí)別-信息' # 記錄格式 )
關(guān)鍵節(jié)點(diǎn)監(jiān)控(示例):
try: 發(fā)送請(qǐng)求... except Exception as e: logging.error(f"插入失敗: {e}") # 記錄錯(cuò)誤快照
五、函數(shù)講解
get_access_token()
def get_access_token(): """獲取飛書API的access_token""" # 定義API請(qǐng)求地址 url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" # 設(shè)置HTTP請(qǐng)求頭(告訴服務(wù)器我們發(fā)送的是JSON數(shù)據(jù)) headers = {"Content-Type": "application/json"} """ 服務(wù)器會(huì)根據(jù) Content-Type 的值,調(diào)用對(duì)應(yīng)的解析方式。例如: 如果是 application/json,服務(wù)器會(huì)用 JSON 解析器處理數(shù)據(jù)。 如果是 application/x-www-form-urlencoded,服務(wù)器會(huì)按表單格式解析數(shù)據(jù)。 """ # 準(zhǔn)備請(qǐng)求數(shù)據(jù)(飛書應(yīng)用的ID和密鑰) data = {"app_id": APP_ID, "app_secret": APP_SECRET} try: # 發(fā)送POST請(qǐng)求到飛書服務(wù)器 response = requests.post(url, headers=headers, json=data) # 檢查響應(yīng)狀態(tài)碼(如果不是200,會(huì)拋出異常) response.raise_for_status() # 解析返回的JSON數(shù)據(jù),提取訪問(wèn)令牌 return response.json()["tenant_access_token"] except Exception as e: # 記錄錯(cuò)誤日志 logging.error(f"獲取access_token失敗: {e}") # 失敗時(shí)返回None return None
關(guān)鍵概念解釋
1. 飛書API訪問(wèn)令牌 (tenant_access_token)
- 這是飛書API的“通行證”,調(diào)用其他API(如發(fā)送消息、讀取數(shù)據(jù))時(shí)必須攜帶它。
- 令牌有效期通常為2小時(shí),需要定期重新獲取。
2. HTTP請(qǐng)求
- POST:一種HTTP方法,表示向服務(wù)器提交數(shù)據(jù)(這里是提交和)。app_idapp_secret
- headers:請(qǐng)求頭, 表示發(fā)送的數(shù)據(jù)是JSON格式。Content-Type: application/json
- data:實(shí)際發(fā)送的數(shù)據(jù),包含飛書應(yīng)用的憑證。
3. APP_ID 和 APP_SECRET
- 這兩個(gè)值需要從飛書開放平臺(tái)注冊(cè)應(yīng)用后獲取。
- 非常重要! 相當(dāng)于你的應(yīng)用賬號(hào)密碼,需嚴(yán)格保密
4. 異常處理 (try-except)
try: response = requests.post(url, headers=headers, json=data) response.raise_for_status() return response.json()["tenant_access_token"] except Exception as e: logging.error(f"獲取access_token失敗: {e}") return None
1. response = requests.post(url, headers=headers, json=data)
作用:向指定的 url 發(fā)送一個(gè) HTTP POST 請(qǐng)求。
參數(shù)說(shuō)明:
url: 目標(biāo) API 接口地址(例如飛書的 tenant_access_token 獲取接口)。
headers: 請(qǐng)求頭,通常包含 Content-Type 等信息(如之前設(shè)置的 application/json)。
json=data: 自動(dòng)將 data 對(duì)象(字典)序列化為 JSON 字符串,并設(shè)置 Content-Type: application/json。
關(guān)鍵點(diǎn):
使用 json=data 比手動(dòng)轉(zhuǎn)換數(shù)據(jù)更簡(jiǎn)潔(等價(jià)于 data=json.dumps(data) + 設(shè)置請(qǐng)求頭)。
2. response.raise_for_status()
作用:檢查 HTTP 響應(yīng)狀態(tài)碼,如果狀態(tài)碼表示錯(cuò)誤(如 4xx 客戶端錯(cuò)誤、5xx 服務(wù)器錯(cuò)誤),直接拋出異常。
常見(jiàn)狀態(tài)碼:
- 200 OK: 請(qǐng)求成功。
- 400 Bad Request: 請(qǐng)求參數(shù)錯(cuò)誤。
- 401 Unauthorized: 身份驗(yàn)證失敗。
- 500 Internal Server Error: 服務(wù)器內(nèi)部錯(cuò)誤。
意義:
如果服務(wù)器返回錯(cuò)誤狀態(tài)碼(如飛書接口返回 {"code": 9999, "msg": "invalid params"}),此方法會(huì)拋出 HTTPError 異常,阻止后續(xù)代碼執(zhí)行,避免處理錯(cuò)誤數(shù)據(jù)。
3. return response.json()["tenant_access_token"]
作用:
response.json(): 將 HTTP 響應(yīng)內(nèi)容解析為 Python 字典(前提是響應(yīng)內(nèi)容是 JSON 格式)。
["tenant_access_token"]: 從解析后的字典中提取 tenant_access_token 字段的值并返回。
關(guān)鍵點(diǎn):
假設(shè)飛書接口返回的 JSON 結(jié)構(gòu)為 {"code":0, "tenant_access_token":"xxx", "expire":7200}。
如果響應(yīng)不是合法的 JSON,response.json() 會(huì)拋出 JSONDecodeError。
4.except Exception as e:
作用:捕獲所有類型的異常(包括 HTTPError、JSONDecodeError、網(wǎng)絡(luò)超時(shí)等)。
細(xì)節(jié):
logging.error(...): 記錄錯(cuò)誤日志(比 print 更規(guī)范,可輸出到文件或監(jiān)控系統(tǒng))。
return None: 返回 None 表示獲取 access_token 失敗,調(diào)用方可通過(guò)判斷返回值是否為 None 處理錯(cuò)誤。
完整邏輯流程圖
開始
│
├─ 發(fā)送 POST 請(qǐng)求 → 成功?
│ ├─ 是 → 檢查狀態(tài)碼 → 正常?
│ │ ├─ 是 → 解析 JSON → 返回 tenant_access_token
│ │ └─ 否 → 拋出 HTTPError
│ └─ 否 → 拋出異常(如網(wǎng)絡(luò)錯(cuò)誤)
│
└─ 捕獲異常 → 記錄日志 → 返回 None
insert_to_feishu()
1.獲取訪問(wèn)令牌
access_token = get_access_token()
調(diào)用 get_access_token() 函數(shù)獲取飛書API的訪問(wèn)令牌(需提前實(shí)現(xiàn))。
若獲取失?。ㄈ缯J(rèn)證錯(cuò)誤),直接返回 False。
2.獲取文檔塊列表
blocks_url = f"https://open.feishu.cn/open-apis/docx/v1/documents/{DOCUMENT_ID}/blocks" headers = {"Authorization": f"Bearer {access_token}"} blocks_response = requests.get(blocks_url, headers=headers)
通過(guò)飛書API獲取文檔的塊(Block)結(jié)構(gòu)。塊是文檔內(nèi)容的組成單元(如段落、標(biāo)題、表格等)。
DOCUMENT_ID 是目標(biāo)文檔的唯一標(biāo)識(shí),需提前從飛書后臺(tái)獲取。
headers = {"Authorization": f"Bearer {access_token}"}
這行代碼用于構(gòu)造一個(gè) HTTP 請(qǐng)求頭(Request Headers),目的是向飛書API服務(wù)端證明當(dāng)前請(qǐng)求的合法性。
認(rèn)證機(jī)制
Bearer Token:這是現(xiàn)代API認(rèn)證的常見(jiàn)方式,屬于OAuth 2.0協(xié)議的一部分。
功能:通過(guò)將 access_token(訪問(wèn)令牌)放在請(qǐng)求頭中,告知飛書服務(wù)器“持有此令牌的用戶/應(yīng)用有權(quán)訪問(wèn)該API”。
類比:類似于現(xiàn)實(shí)中的“門禁卡”,只有持有有效卡(access_token)的人才能通過(guò)門禁(API權(quán)限校驗(yàn))。
格式說(shuō)明
鍵值對(duì)結(jié)構(gòu):
鍵(Key): Authorization
值(Value): Bearer {access_token}
(將 access_token 的值替換到 {access_token} 的位置)
示例:
# 假設(shè) access_token = "abc123xyz" headers = {"Authorization": "Bearer abc123xyz"}
技術(shù)細(xì)節(jié)
為什么必須用 Bearer 前綴?
這是OAuth 2.0的標(biāo)準(zhǔn)規(guī)范,用于明確令牌類型。服務(wù)端會(huì)根據(jù)前綴判斷認(rèn)證方式。
access_token 從何而來(lái)?
通常通過(guò)飛書開放平臺(tái)的身份認(rèn)證流程生成,例如:
- 用戶登錄后授權(quán)獲取
- 應(yīng)用自身體驗(yàn)的令牌(如機(jī)器人或服務(wù)端API調(diào)用
實(shí)際應(yīng)用場(chǎng)景
在飛書API請(qǐng)求中,所有需要權(quán)限的操作(如讀寫文檔、獲取用戶信息等)都必須攜帶此頭。例如:
# 發(fā)送請(qǐng)求時(shí)附加 headers response = requests.get(url, headers=headers)
3.飛書文檔中獲取所有內(nèi)容塊
這三行代碼用于 從飛書文檔中獲取所有內(nèi)容塊(Blocks),是操作飛書文檔的核心步驟。
發(fā)送HTTP GET請(qǐng)求
blocks_response = requests.get(blocks_url, headers=headers)
功能:
向飛書API發(fā)送一個(gè) GET請(qǐng)求,目標(biāo)地址是 blocks_url(例如 https://open.feishu.cn/open-apis/docx/v1/documents/{document_id}/blocks)。
參數(shù)說(shuō)明:
headers=headers:攜帶認(rèn)證頭(包含 Authorization: Bearer {access_token}),用于權(quán)限驗(yàn)證。
返回值:
blocks_response 是一個(gè) Response 對(duì)象,包含服務(wù)端返回的原始HTTP響應(yīng)。
檢查HTTP響應(yīng)狀態(tài)
blocks_response.raise_for_status()
功能:
自動(dòng)檢測(cè)HTTP響應(yīng)狀態(tài)碼。如果狀態(tài)碼是 4xx(客戶端錯(cuò)誤) 或 5xx(服務(wù)端錯(cuò)誤),直接拋出異常(如 HTTPError),終止后續(xù)代碼執(zhí)行。
為什么需要它?
避免在請(qǐng)求失敗時(shí)繼續(xù)處理無(wú)效數(shù)據(jù)(例如令牌過(guò)期、URL錯(cuò)誤、權(quán)限不足等)。
典型錯(cuò)誤場(chǎng)景:
- 401 Unauthorized:access_token 失效或未傳。
- 404 Not Found:blocks_url 地址錯(cuò)誤或文檔不存在。
解析JSON數(shù)據(jù)并提取內(nèi)容塊
blocks = blocks_response.json()["data"]["items"]
將HTTP響應(yīng)的原始內(nèi)容(JSON格式)解析為Python字典,并提取其中的文檔塊列表。
數(shù)據(jù)結(jié)構(gòu)(以飛書文檔API為例):
{ "code": 0, "data": { "items": [ {"block_id": "xxxx", "content": "文本內(nèi)容1"}, {"block_id": "yyyy", "content": "文本內(nèi)容2"} ] } }
它的操作可以拆解為以下步驟:
blocks_response.json():將 HTTP 響應(yīng)的原始內(nèi)容(JSON 格式)轉(zhuǎn)換為 Python 的字典(dict)或列表(list)。
["data"]:從 JSON 字典中提取鍵為 "data" 的值(通常包含核心數(shù)據(jù))。
["items"]:從 "data" 對(duì)應(yīng)的字典中,進(jìn)一步提取鍵為 "items" 的值(通常是一個(gè)列表,包含多個(gè)數(shù)據(jù)項(xiàng))。
結(jié)果:
blocks 變量存儲(chǔ)所有文檔塊的列表,后續(xù)可用于遍歷、修改或插入新內(nèi)容。
示例:
當(dāng)我們將這個(gè)表格轉(zhuǎn)換為 Python 的字典列表時(shí),結(jié)果如下:
data = { "code": 0, "message": "成功", "data": { "items": [ {"姓名": "張三", "年齡": 25, "城市": "北京"}, {"姓名": "李四", "年齡": 30, "城市": "上海"} ] } } # 提取表格中的每一行(即 items 列表) items = data["data"]["items"]
此時(shí) items 的值是:
[
{"姓名": "張三", "年齡": 25, "城市": "北京"},
{"姓名": "李四", "年齡": 30, "城市": "上海"}
]
類比解釋
data["data"]
類似于 Excel 表格的整個(gè)數(shù)據(jù)區(qū)域(包含表頭和所有行),對(duì)應(yīng)代碼中 data 字段的內(nèi)容。
data["data"]["items"]
類似于 Excel 表格中所有行的數(shù)據(jù)(每一行是一個(gè)字典),對(duì)應(yīng)代碼中的 items 列表。
最終結(jié)果 blocks
就是一個(gè)列表,每個(gè)元素代表一個(gè)獨(dú)立的“塊”(對(duì)應(yīng) Excel 中的一行),例如:
blocks = [ {"block_id": "段落1", "text": "這是第一段內(nèi)容"}, {"block_id": "圖片1", "url": "https://example.com/image.jpg"} ]
4.定位最后一個(gè)塊的ID
last_block_id = blocks[-1]["block_id"] if blocks else None
從返回的塊列表中提取最后一個(gè)塊的 block_id。
若文檔為空(無(wú)任何塊),last_block_id 為 None,可能導(dǎo)致后續(xù)插入失敗。
5.插入新內(nèi)容
insert_url = f"https://open.feishu.cn/open-apis/docx/v1/documents/{DOCUMENT_ID}/blocks/{last_block_id}/insert" data = { "content": f"**數(shù)據(jù)更新時(shí)間:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}**\n{content}", "position": "after" } insert_response = requests.post(insert_url, headers=headers, json=data)
在最后一個(gè)塊之后插入新內(nèi)容。
content 字段包含帶時(shí)間戳的加粗標(biāo)題(Markdown語(yǔ)法)和傳入的 content 參數(shù)。
飛書API支持富文本格式,此處使用 ** 表示加粗,實(shí)際可能需要根據(jù)API要求調(diào)整格式
- "content": f"**數(shù)據(jù)更新時(shí)間:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}**\n{content}",
- "position": "after" # 在最后一個(gè)塊后插入
這是**字典(dict)**中的兩個(gè)鍵值對(duì),通常用于配置內(nèi)容插入邏輯(例如生成報(bào)告、更新文檔等場(chǎng)景)。
(1) "content": ...
功能:定義要插入的文本內(nèi)容,包含動(dòng)態(tài)時(shí)間和原始內(nèi)容。
細(xì)節(jié):
- f"...":使用 Python 的 f-string 動(dòng)態(tài)生成字符串。
- datetime.now():獲取當(dāng)前時(shí)間。
- strftime('%Y-%m-%d %H:%M:%S'):將時(shí)間格式化為 年-月-日 時(shí):分:秒(例如 2023-10-05 14:30:00)。
- **數(shù)據(jù)更新時(shí)間:...**:用 Markdown 的粗體語(yǔ)法包裹時(shí)間戳,使其突出顯示。
- \n{content}:換行后追加原始內(nèi)容(假設(shè) content 是已定義的變量)。
(2) "position": "after"
功能:指定插入位置為目標(biāo)位置之后(例如在文檔的最后一個(gè)段落/區(qū)塊后追加內(nèi)容)。
常見(jiàn)值:
- "after":在指定位置后插入。
- "before":在指定位置前插入。
- "replace":替換原有內(nèi)容。
實(shí)際輸出示例
假設(shè) content 的值為 "這是原始內(nèi)容",則生成的 "content" 結(jié)果為:
效果:在原始內(nèi)容前添加時(shí)間戳,并用粗體顯示。
**數(shù)據(jù)更新時(shí)間:2023-10-05 14:30:00**
這是原始內(nèi)容
insert_response = requests.post(insert_url, headers=headers, json=data) insert_response.raise_for_status() logging.info("數(shù)據(jù)插入成功!")
這段代碼用于向指定的URL發(fā)送HTTP POST請(qǐng)求,插入數(shù)據(jù)并處理響應(yīng)。
6.異常處理
try: # ...請(qǐng)求代碼... except Exception as e: logging.error(f"插入數(shù)據(jù)失敗: {e}") return False
捕獲網(wǎng)絡(luò)錯(cuò)誤、API響應(yīng)錯(cuò)誤等異常,記錄日志并返回 False。
六、main()
def main(): """主函數(shù):讀取Excel并同步到飛書""" try: # 讀取Excel數(shù)據(jù) df = pd.read_excel("data.xlsx") # 替換為你的Excel路徑 markdown_table = df.to_markdown(index=False) # 插入到飛書文檔 if insert_to_feishu(markdown_table): print("同步成功!") else: print("同步失敗,請(qǐng)查看日志文件。") except Exception as e: logging.error(f"主流程異常: {e}") markdown_table = df.to_markdown(index=False)
代碼功能
- 作用:將 pandas 的 DataFrame (df) 轉(zhuǎn)換為 Markdown 格式的表格字符串,并保存到變量 markdown_table 中。
- 參數(shù) index=False:表示生成的表格中不包含行索引列(默認(rèn)會(huì)顯示索引)。
示例與輸出
假設(shè)有一個(gè) DataFrame:
import pandas as pd data = { "Name": ["Alice", "Bob", "Charlie"], "Age": [25, 30, 35], "City": ["New York", "London", "Tokyo"] } df = pd.DataFrame(data)
執(zhí)行代碼:
markdown_table = df.to_markdown(index=False) print(markdown_table)
輸出結(jié)果:
| Name | Age | City |
|---------|-------|----------|
| Alice | 25 | New York |
| Bob | 30 | London |
| Charlie | 35 | Tokyo |
七、相關(guān)庫(kù)函數(shù)
1. import pandas as pd
用途:數(shù)據(jù)分析和處理(表格數(shù)據(jù)操作)。
常用函數(shù)/類:
- pd.read_csv('file.csv'):讀取 CSV 文件生成 DataFrame。
- df.to_csv('output.csv'):將 DataFrame 保存為 CSV 文件。
- df.head(n):顯示 DataFrame 前 n 行(默認(rèn) 5 行)。
df.merge(df2, on='key'):按列合并兩個(gè) DataFrame。 - df.groupby('column').sum():按列分組聚合數(shù)據(jù)。 - pd.DataFrame(data):從字典/列表創(chuàng)建 DataFrame。
# 示例:讀取 CSV 并處理數(shù)據(jù) data = pd.read_csv("data.csv") filtered_data = data[data["age"] > 18] filtered_data.to_csv("adults.csv")
2. import requests
用途:發(fā)送 HTTP 請(qǐng)求(如 API 調(diào)用、網(wǎng)頁(yè)抓?。?。
常用函數(shù)/方法:
requests.get(url, params={}):發(fā)送 GET 請(qǐng)求。
requests.post(url, data={}):發(fā)送 POST 請(qǐng)求。 - response.json():將響應(yīng)內(nèi)容解析為 JSON。 - response.status_code:獲取 HTTP 狀態(tài)碼(如 200 表示成功)。 - response.text:獲取原始文本響應(yīng)內(nèi)容。
# 示例:調(diào)用 API 獲取數(shù)據(jù) response = requests.get("https://api.example.com/data") if response.status_code == 200: data = response.json() print(data["results"])
3. import logging
用途:記錄程序運(yùn)行日志(調(diào)試、警告、錯(cuò)誤等)。
常用函數(shù)/配置:
- logging.basicConfig(level=logging.INFO):設(shè)置日志級(jí)別。
- logging.info('message'):記錄一般信息。
- logging.warning('message'):記錄警告。
- logging.error('message'):記錄錯(cuò)誤。
- logger = logging.getLogger(__name__):創(chuàng)建自定義日志記錄器。
# 示例:記錄程序運(yùn)行狀態(tài) logging.basicConfig(level=logging.INFO) logging.info("程序啟動(dòng)") try: # 某些操作 except Exception as e: logging.error(f"發(fā)生錯(cuò)誤: {e}")
4. from datetime import datetime
用途:處理日期和時(shí)間。
常用函數(shù)/方法:
- datetime.now():獲取當(dāng)前時(shí)間。
- datetime.strftime('%Y-%m-%d'):格式化時(shí)間為字符串。
- datetime.strptime('2023-10-05', '%Y-%m-%d'):將字符串解析為時(shí)間對(duì)象。
- datetime.timestamp():獲取時(shí)間戳(秒數(shù))。
# 示例:生成帶時(shí)間戳的日志 current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") print(f"操作時(shí)間: {current_time}")
八、完整代碼
import pandas as pd import requests import logging from datetime import datetime # 配置日志記錄 logging.basicConfig( filename='feishu_sync.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) """ 1.logging.basicConfig(...) logging 是 Python 標(biāo)準(zhǔn)庫(kù)中的日志模塊,用于記錄程序的運(yùn)行狀態(tài),方便調(diào)試和排查問(wèn)題。 basicConfig() 方法用于配置日志系統(tǒng)的基本設(shè)置。 2.filename='feishu_sync.log' 指定日志輸出的文件名為 feishu_sync.log,所有日志信息都會(huì)被寫入該文件。 這樣可以在程序運(yùn)行后,查看 feishu_sync.log 文件來(lái)了解程序的執(zhí)行情況。 3.level=logging.INFO 設(shè)置日志的最低級(jí)別為 INFO,即只記錄 INFO 及更高級(jí)別的日志(包括 WARNING、ERROR 和 CRITICAL)。 低于 INFO 級(jí)別的 DEBUG 級(jí)日志不會(huì)被記錄。 4.format='%(asctime)s - %(levelname)s - %(message)s' 指定日志的輸出格式,其中: %(asctime)s:時(shí)間戳,表示日志記錄的時(shí)間(格式如 2025-02-18 12:34:56)。 %(levelname)s:日志級(jí)別,如 INFO、ERROR 等。 %(message)s:具體的日志消息內(nèi)容。 """ # 飛書API配置 APP_ID = "your_app_id" APP_SECRET = "your_app_secret" DOCUMENT_ID = "Gu4LwF32Ci0OUakZo50cQ8p2njk" # 目標(biāo)云文檔的ID def get_access_token(): """獲取飛書API的access_token""" url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" headers = {"Content-Type": "application/json"} data = {"app_id": APP_ID, "app_secret": APP_SECRET} try: response = requests.post(url, headers=headers, json=data) response.raise_for_status() return response.json()["tenant_access_token"] except Exception as e: logging.error(f"獲取access_token失敗: {e}") return None """ requests.post(url, headers=headers, json=data):使用 requests 庫(kù)發(fā)送一個(gè) POST 請(qǐng)求到指定的 URL,并攜帶請(qǐng)求頭和請(qǐng)求體數(shù)據(jù)。json=data 會(huì)自動(dòng)將字典 data 轉(zhuǎn)換為 JSON 格式的字符串。 response.raise_for_status():檢查響應(yīng)的狀態(tài)碼,如果狀態(tài)碼不是 200(表示請(qǐng)求成功),則拋出 HTTPError 異常。 response.json()["tenant_access_token"]:將響應(yīng)的內(nèi)容解析為 JSON 格式,并返回其中的 tenant_access_token 字段,即獲取到的租戶訪問(wèn)令牌。 except Exception as e::捕獲所有異常,并將異常對(duì)象賦值給變量 e。 logging.error(f"獲取access_token失敗: {e}"):使用 logging 模塊記錄錯(cuò)誤信息,方便后續(xù)排查問(wèn)題。 return None:如果發(fā)生異常,返回 None 表示獲取令牌失敗。 """ def insert_to_feishu(content): """向飛書文檔插入內(nèi)容""" access_token = get_access_token() if not access_token: return False # 步驟1:獲取文檔塊列表,找到最后一個(gè)塊的位置 blocks_url = f"https://open.feishu.cn/open-apis/docx/v1/documents/{DOCUMENT_ID}/blocks" headers = {"Authorization": f"Bearer {access_token}"} try: # 獲取文檔結(jié)構(gòu) blocks_response = requests.get(blocks_url, headers=headers) blocks_response.raise_for_status() blocks = blocks_response.json()["data"]["items"] # 找到最后一個(gè)塊的ID(用于插入位置) last_block_id = blocks[-1]["block_id"] if blocks else None # 步驟2:插入新內(nèi)容到文檔末尾 insert_url = f"https://open.feishu.cn/open-apis/docx/v1/documents/{DOCUMENT_ID}/blocks/{last_block_id}/insert" data = { "content": f"**數(shù)據(jù)更新時(shí)間:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}**\n{content}", "position": "after" # 在最后一個(gè)塊后插入 } insert_response = requests.post(insert_url, headers=headers, json=data) insert_response.raise_for_status() logging.info("數(shù)據(jù)插入成功!") return True except Exception as e: logging.error(f"插入數(shù)據(jù)失敗: {e}") return False def main(): """主函數(shù):讀取Excel并同步到飛書""" try: # 讀取Excel數(shù)據(jù) df = pd.read_excel("data.xlsx") # 替換為你的Excel路徑 markdown_table = df.to_markdown(index=False) # 插入到飛書文檔 if insert_to_feishu(markdown_table): print("同步成功!") else: print("同步失敗,請(qǐng)查看日志文件。") except Exception as e: logging.error(f"主流程異常: {e}") if __name__ == "__main__": main()
以上就是Python實(shí)現(xiàn)Excel數(shù)據(jù)同步到飛書文檔的詳細(xì)內(nèi)容,更多關(guān)于Python Excel數(shù)據(jù)同步到飛書的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python生成動(dòng)態(tài)路由軌跡圖的示例詳解
在當(dāng)今的數(shù)據(jù)驅(qū)動(dòng)時(shí)代,可視化技術(shù)在數(shù)據(jù)分析和決策支持中扮演著越來(lái)越重要的角色,本文將介紹如何使用Python來(lái)生成動(dòng)態(tài)的路由軌跡圖,需要的可以了解下2025-02-02python 實(shí)現(xiàn)單通道轉(zhuǎn)3通道
今天小編就為大家分享一篇python 實(shí)現(xiàn)單通道轉(zhuǎn)3通道,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12CentOS中使用virtualenv搭建python3環(huán)境
virtualenv可以搭建虛擬且獨(dú)立的python環(huán)境,可以使每個(gè)項(xiàng)目環(huán)境與其他項(xiàng)目獨(dú)立開來(lái),保持環(huán)境的干凈,解決包沖突問(wèn)題。下面我們來(lái)詳細(xì)探討下centos中如何來(lái)搭建。2015-06-06利用python進(jìn)行矩陣運(yùn)算實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于如何利用python進(jìn)行矩陣運(yùn)算的相關(guān)資料,Numpy是Python編程語(yǔ)言中的一個(gè)核心庫(kù),專門用于處理多維數(shù)據(jù)和矩陣運(yùn)算,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-12-12PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟
這篇文章主要介紹了PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-09-09Python實(shí)現(xiàn)繁體中文與簡(jiǎn)體中文相互轉(zhuǎn)換的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)繁體中文與簡(jiǎn)體中文相互轉(zhuǎn)換的方法,涉及Python基于第三方模塊進(jìn)行編碼轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下2018-12-12基于Python實(shí)現(xiàn)語(yǔ)音識(shí)別和語(yǔ)音轉(zhuǎn)文字
這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)語(yǔ)音識(shí)別和語(yǔ)音轉(zhuǎn)文字功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-09-09Python?matplotlib實(shí)戰(zhàn)之散點(diǎn)圖繪制
散點(diǎn)圖,又名點(diǎn)圖、散布圖、X-Y圖,是將所有的數(shù)據(jù)以點(diǎn)的形式展現(xiàn)在平面直角坐標(biāo)系上的統(tǒng)計(jì)圖表,本文主要為大家介紹了如何使用Matplotlib繪制散點(diǎn)圖,需要的可以參考下2023-08-08Python?識(shí)別錄音并轉(zhuǎn)為文字的實(shí)現(xiàn)
本文主要介紹了Python?識(shí)別錄音并轉(zhuǎn)為文字的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03