Python實現(xiàn)獲取手機通訊錄文件并導(dǎo)出為excel
核心功能與解決的實際問題
這段代碼的核心功能是解析從手機導(dǎo)出的VCF格式通訊錄文件,并將其中的聯(lián)系人信息(如姓名、電話號碼、郵箱等)轉(zhuǎn)換并保存為結(jié)構(gòu)清晰、易于編輯的Excel表格。它專門解決了VCF文件(vCard格式)用文本編輯器查看雜亂無章、無法直接篩選或批量編輯的痛點,使得備份的通訊錄數(shù)據(jù)變得可讀、可管理。
完整的聯(lián)系人信息提取與導(dǎo)出流程
程序能夠系統(tǒng)性地遍歷VCF文件,識別每個以"BEGIN:VCARD"開始、“END:VCARD"結(jié)束的聯(lián)系人數(shù)據(jù)塊,并從中提取關(guān)鍵字段。解析出的信息會結(jié)構(gòu)化地存入數(shù)據(jù)集合,最后利用pandas庫生成包含"姓名”、“電話”、"郵箱"等列的Excel文件(.xlsx格式),確保所有聯(lián)系信息一目了然,方便后續(xù)的查找、編輯或?qū)肫渌O(shè)備。

實現(xiàn)代碼
import vobject
import chardet
import pandas as pd
import os
def debug_vcf_file(file_path):
"""
調(diào)試VCF文件:檢查編碼、文件結(jié)構(gòu)和內(nèi)容
"""
print("=== 開始調(diào)試VCF文件 ===")
# 檢查文件是否存在
if not os.path.exists(file_path):
print(f"錯誤:文件 '{file_path}' 不存在")
return False
# 檢查文件大小
file_size = os.path.getsize(file_path)
print(f"文件大小: {file_size} 字節(jié)")
if file_size == 0:
print("錯誤:文件為空")
return False
# 讀取原始字節(jié)數(shù)據(jù)
with open(file_path, 'rb') as f:
raw_data = f.read()
# 檢測編碼
encoding_result = chardet.detect(raw_data)
detected_encoding = encoding_result['encoding']
confidence = encoding_result['confidence']
print(f"檢測到的編碼: {detected_encoding} (置信度: {confidence:.2f})")
# 嘗試不同編碼
encodings_to_try = [detected_encoding, 'gbk', 'gb2312', 'utf-8', 'iso-8859-1']
for encoding in encodings_to_try:
if not encoding:
continue
try:
content = raw_data.decode(encoding)
print(f"? 成功使用 {encoding} 編碼解碼")
# 檢查VCF基本結(jié)構(gòu)
if 'BEGIN:VCARD' in content and 'END:VCARD' in content:
vcard_count = content.count('BEGIN:VCARD')
print(f"找到 {vcard_count} 個聯(lián)系人卡片")
# 顯示前500個字符作為樣本
sample = content[:500]
print("文件內(nèi)容樣本:")
print("---" + sample + "---")
return True, content, encoding
else:
print(f"× 使用 {encoding} 解碼但未找到VCARD結(jié)構(gòu)")
except UnicodeDecodeError as e:
print(f"× {encoding} 編碼解碼失敗: {e}")
except Exception as e:
print(f"× {encoding} 處理過程中出錯: {e}")
# 最后嘗試忽略錯誤模式
try:
content = raw_data.decode('utf-8', errors='ignore')
print("最后嘗試:使用UTF-8忽略錯誤模式解碼")
return True, content, 'utf-8 (errors ignored)'
except Exception as e:
print(f"最終解碼失敗: {e}")
return False, None, None
def parse_vcf_with_debug(file_path):
"""
解析VCF文件并生成Excel表格
"""
# 調(diào)試文件
debug_result, vcf_content, used_encoding = debug_vcf_file(file_path)
if not debug_result:
print("文件調(diào)試失敗,無法繼續(xù)解析")
return []
contacts = []
print(f"\n=== 開始解析VCF內(nèi)容(使用編碼: {used_encoding})===")
try:
# 分割vCard塊
vcard_blocks = vcf_content.split('BEGIN:VCARD')
for i, block in enumerate(vcard_blocks):
if not block.strip() or 'END:VCARD' not in block:
continue
# 重新構(gòu)建完整的vCard
vcard_text = 'BEGIN:VCARD' + block
try:
vcard = vobject.readOne(vcard_text)
contact_info = {'序號': i}
# 提取姓名
if hasattr(vcard, 'fn') and vcard.fn:
contact_info['姓名'] = str(vcard.fn.value)
print(f"聯(lián)系人 {i}: 找到姓名 - {vcard.fn.value}")
else:
contact_info['姓名'] = '未知'
print(f"聯(lián)系人 {i}: 未找到姓名字段")
# 提取電話
contact_info['電話'] = ''
if hasattr(vcard, 'tel'):
phones = []
if isinstance(vcard.tel, list):
for tel in vcard.tel:
if hasattr(tel, 'value') and tel.value:
phones.append(str(tel.value))
elif hasattr(vcard.tel, 'value') and vcard.tel.value:
phones.append(str(vcard.tel.value))
if phones:
contact_info['電話'] = '; '.join(phones)
print(f"聯(lián)系人 {i}: 找到電話 - {phones}")
else:
print(f"聯(lián)系人 {i}: 找到TEL字段但值為空")
# 提取其他信息
if hasattr(vcard, 'email'):
emails = []
if isinstance(vcard.email, list):
for email in vcard.email:
if email.value:
emails.append(str(email.value))
elif vcard.email.value:
emails.append(str(vcard.email.value))
contact_info['郵箱'] = '; '.join(emails) if emails else ''
contacts.append(contact_info)
print(f"? 成功解析聯(lián)系人 {i}: {contact_info['姓名']}")
except Exception as e:
print(f"× 解析聯(lián)系人 {i} 時出錯: {e}")
# 打印出錯的vCard內(nèi)容前200字符用于調(diào)試
print(f"錯誤vCard樣本: {vcard_text[:200]}")
continue
except Exception as e:
print(f"解析過程中出現(xiàn)嚴(yán)重錯誤: {e}")
return contacts
def save_contacts_to_excel(contacts, output_file='contacts.xlsx'):
"""
將聯(lián)系人保存到Excel文件
"""
if not contacts:
print("沒有聯(lián)系人數(shù)據(jù)可保存")
return False
try:
# 創(chuàng)建DataFrame
df = pd.DataFrame(contacts)
# 重新排列列順序
columns_order = ['序號', '姓名', '電話', '郵箱']
existing_columns = [col for col in columns_order if col in df.columns]
df = df[existing_columns]
# 保存到Excel
df.to_excel(output_file, index=False, engine='openpyxl')
print(f"? 成功生成Excel文件: {output_file}")
print(f"? 共保存 {len(contacts)} 個聯(lián)系人")
# 顯示前幾行作為預(yù)覽
print("\n前5個聯(lián)系人預(yù)覽:")
print(df.head())
return True
except Exception as e:
print(f"× 生成Excel文件時出錯: {e}")
return False
# 主執(zhí)行函數(shù)
def main():
vcf_file_path = "你的通訊錄.vcf" # 請?zhí)鎿Q為您的VCF文件路徑
print("手機VCF聯(lián)系人解析工具")
print("=" * 50)
# 解析VCF文件
contacts_list = parse_vcf_with_debug(vcf_file_path)
if contacts_list:
# 生成Excel文件
save_contacts_to_excel(contacts_list)
print(f"\n解析完成!成功處理 {len(contacts_list)} 個聯(lián)系人")
else:
print("\n解析失敗,未找到有效聯(lián)系人")
if __name__ == "__main__":
main()
效果如下:

以上就是Python實現(xiàn)獲取手機通訊錄文件并導(dǎo)出為excel的詳細(xì)內(nèi)容,更多關(guān)于Python獲取手機通訊錄的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python運用sklearn實現(xiàn)KNN分類算法
這篇文章主要為大家詳細(xì)介紹了python運用sklearn實現(xiàn)KNN分類算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-10-10
python中類名和文件名的命名規(guī)則詳細(xì)解釋
在Python中文件名命名規(guī)則對于代碼的可讀性和可維護性至關(guān)重要,這篇文章主要介紹了python中類名和文件名命名規(guī)則的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-10-10
Python PyQt5實戰(zhàn)項目之網(wǎng)速監(jiān)控器的實現(xiàn)
PyQt5以一套Python模塊的形式來實現(xiàn)功能。它包含了超過620個類,600個方法和函數(shù)。它是一個多平臺的工具套件,它可以運行在所有的主流操作系統(tǒng)中,包含Unix,Windows和Mac OS。PyQt5采用雙重許可模式。開發(fā)者可以在GPL和社區(qū)授權(quán)之間選擇2021-11-11

