來源
整理大量通訊錄時,發現從手機上下載的CSV文件不易轉成EXCEL文件(QQ通訊錄和百度雲盤都試過了,CSV文件過大無法加載),導致整理起來特別麻煩,故試圖自己寫一個小程序來處理文件。
分析CSV文件
用文本編輯器打開vcf一看,就是文本格式,我只需要把它轉換成csv格式,然後就可以導入到Excel中了
BEGIN:VCARD
VERSION:2.1
N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E5=95=8A=6C;;;;
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E5=95=8A=6C
LATESTDATE:201909011513
COUNTRYISO:TH
OPPO_RECENT_CALL:NULL
TEL;CELL:83834033
X-OPPO-GROUP;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=51=51=E5=90=8C=E6=AD=A5=E5=8A=A9=E6=89=8B=32=30=31=36=31=30=30=31
END:VCARD
從內容看,只需要取"FN:"、"TEL"打頭的字段,遇到"END"再開始下一個名片。
由FN觀察得知,其編碼爲QUOTED-PRINTABLE
,故可引入quopri
模塊來解碼。
代碼
import quopri #quoted-printable編解碼
with open("I:\contacts.vcf", 'r') as rf, open('I:\contacts.txt', 'w',encoding='utf-8') as wf:
content = ['', '', '', '']
tel = 0
not_1_line=0
fn='' #多行姓名
for line in rf.readlines():
if line.startswith('FN') or not_1_line: #姓名 此處存在多行的情況
if len(line)>1:
if line[-2]=='=': #說明不止1行
not_1_line=1
fn+=line[:-2] #刪除最後兩位——'=\n'
continue
else: #到底了
not_1_line=0
fn+=line.strip('\n')
line=fn
fn='' #清空
pos=line.find(':')
qp_origin= line[pos+1:].strip().encode() #b'=E5=95=8A=6C'
content[0]=quopri.decodestring(qp_origin).decode('utf-8')
elif line.startswith('TEL'):
if tel > 2: #最多三個電話
continue
pos = line.find(':')
content[tel + 1] = line[pos + 1:].strip()
tel = tel + 1
elif line.startswith('END'):
str = '\t'.join(content) + '\n' #'gbk' codec can't encode character '\u270c' in position 5: illegal multibyte sequence,存在特殊字符
#將編碼方式修改爲UTF-8——open默認編解碼非utf-8
if '篩選條件' in str: #此處添加篩選條件
wf.write(str)
content = ['', '', '', '']
tel = 0
總結
此程序主要難點就是編碼的轉換。
此外,FN有時會超過兩行或者三行,必須要特別考慮,不然會出現無法解碼的情況
轉換出來的爲txt文件,若需要excel文件,直接全選複製便可
錯誤
'gbk' codec can't encode character '\u270c' in position 5: illegal multibyte sequence
調試中遇到如上錯誤,經過排查是緣由open
默認編碼非utf-8,指定一下便好