zoukankan      html  css  js  c++  java
  • 利用beautifulsoup4解析Kindle笔记

    目录

    1.需求说明

    拥有Kindle Paperwhite 3 ( KPW3 )设备,平常会在KPW3、android手机、ipad及电脑等多端设备阅读电子书,阅读过程中会对书籍标记、做笔记,比较奇怪的是KPW3上的标记、笔记能同步到其他终端上,反过来虽然可以同步到KPW3上,但是标注及笔记无法记录到My Clippings.txt,以至于无法进一步加工处理读书笔记,所以利用android手机的kindle的笔记导出功能,将一本书籍的所有笔记以html导出,进一步解析合并至My Clippings.txt及处理到Variety、anki等应用上。

    2.系统环境

    1. #系统环境 
    2. !lsb_release -a 
    1. No LSB modules are available. 
    2. Distributor ID: LinuxMint 
    3. Description: Linux Mint 19.3 Tricia 
    4. Release: 19.3 
    5. Codename: tricia 
    1. #Python及相关库版本 
    2. !python --version 
    3. !python -m pip list --format=columns | grep beautifulsoup4 
    4. !python -m pip list --format=columns | grep lxml 
    1. Python 3.6.9 
    2. beautifulsoup4 4.9.0  
    3. lxml 4.5.0  

    3.利用app版kindle导出读书笔记

    确保android上的Kindle笔记已经完整(可能出现手机1笔记完整,手机2只有一个字,如下图,这种情况只能定位过去再标记一遍)

    多端同步出现笔记不一致问题
    多端同步出现笔记不一致问题

    笔记完整后,使用无格式导出笔记,导出流程如下图:

    第一步 第二步

    笔记导出后,效果如下图:

    导出的kindle笔记
    导出的kindle笔记

    4.解析html笔记

    4.1解析书籍基本信息

    1. #导入库 
    2. import re 
    3. from bs4 import BeautifulSoup 
    4. from lxml.html.clean import unicode 
    5.  
    6. #创建Beautifulsoup对象 
    7. soup=BeautifulSoup(open('./demo.html'),features='html.parser') 
    8.  
    9. #获取书籍名称及作者 
    10. bookname=soup.find_all('div',class_='bookTitle')[0].text.strip() 
    11. authors=soup.find_all('div',class_='authors')[0].text.strip() 
    12. print(bookname,authors) 
    1. 拆掉思维里的墙:原来我还可以这样活 古典 

    4.2解析书籍笔记

    1. #所有笔记内容 
    2. allcontents=soup.contents[3].contents[3].contents[1] 
    3.  
    4. #遍历所有笔记内容 
    5. allnotes=[] 
    6. takenoteflag=False 
    7. for conind in range(11,len(allcontents)): 
    8. content=BeautifulSoup(unicode(allcontents.contents[conind])) 
    9. if len(content)==0: 
    10. continue 
    11. if conind==11: 
    12. note={'sectionHeading':'','noteHeading':{'markColor':'','markPosition':''},'noteText':'','takenote':{'takePosition':'','note':''}}  
    13. #根据css样式区分内容 
    14. div=content.select('div') 
    15. divclass=div[0].get("class")[0] 
    16. #笔记所处章节 
    17. if divclass=='sectionHeading': 
    18. note['sectionHeading']=content.text.strip().replace(' ','') 
    19. #笔记样式 
    20. elif divclass=='noteHeading': 
    21. if takenoteflag: 
    22. markpos=re.findall(r'd+',content.text.strip().replace(' ',''))[0] 
    23. note['takenote']['markPosition']=markpos 
    24. else: 
    25. markclo=content.span.text.strip().replace(' ','') 
    26. markpos=re.findall(r'd+',content.text.strip().replace(' ',''))[0] 
    27. note['noteHeading']['markColor']=markclo 
    28. note['noteHeading']['markPosition']=markpos 
    29. #自己做了笔记 
    30. elif divclass=='noteText' and takenoteflag: 
    31. note['takenote']['note']=content.text.strip().replace(' ','') 
    32. takenoteflag=False 
    33. allnotes.append(note) 
    34. note={'sectionHeading':note['sectionHeading'],'noteHeading':{'markColor':'','markPosition':''},'noteText':'','takenote':{'takePosition':'','note':''}} 
    35. #仅仅是标记笔记 
    36. elif divclass=='noteText' and not takenoteflag: 
    37. note['noteText']=content.text.strip().replace(' ','') 
    38.  
    39. #判断后续是否有笔记 
    40. strtind=1 
    41. nextnote=BeautifulSoup(unicode(allcontents.contents[conind+strtind])) 
    42. while len(nextnote)==0 and (conind+strtind)<len(allcontents): 
    43. nextnote=BeautifulSoup(unicode(allcontents.contents[conind+strtind])) 
    44. strtind+=1 
    45. if '笔记' in nextnote.text.strip().replace(' ',''): 
    46. takenoteflag=True 
    47. else: 
    48. allnotes.append(note) 
    49. note={'sectionHeading':note['sectionHeading'],'noteHeading':{'markColor':'','markPosition':''},'noteText':'','takenote':{'takePosition':'','note':''}} 
    50. # print(allnotes) 

    5.应用html笔记

    5.1追加至kindle笔记管理文件My Clippings.txt

    解析了笔记内容,按照My Clippings.txt文件中的标记、笔记格式,将导出笔记内容追加至My Clippings.txt,笔记合并后,可利用现有的诸如clippings.io书见等工具进行笔记管理。

    注意:由于导出笔记不含时间信息,因此至获取当前系统时间作为笔记时间,该时间非真实做笔记时间

    1. #获取当前时间 
    2. import time 
    3. def Getnowdate(): 
    4. week_day_dict = { 
    5. 0 : '星期一', 
    6. 1 : '星期二', 
    7. 2 : '星期三', 
    8. 3 : '星期四', 
    9. 4 : '星期五', 
    10. 5 : '星期六', 
    11. 6 : '星期天', 
    12. } 
    13. loctime=time.localtime() 
    14. years=time.strftime("%Y年%-m月%-d日", loctime) 
    15. weeks=week_day_dict[loctime[6]] 
    16.  
    17. if loctime[3]<=12: 
    18. times=time.strftime("上午%-H:%-M:%S", loctime) 
    19. else: 
    20. times='下午'+time.localtime()[3]-12+time.strftime(":%M:%S", loctime) 
    21. nowdate=years+weeks+' '+times 
    22. return nowdate 
    1. #读入已做的笔记 
    2. existnotes=open('My Clippings.txt','r').readlines() 
    3.  
    4. #写入文件 
    5. fw=open('My Clippings.txt','a') 
    6. for noteind in range(0,len(allnotes)): 
    7. if allnotes[noteind]['takenote']['note']!='': 
    8.  
    9. if (allnotes[noteind]['noteText'].replace(' ','')+' ') not in existnotes: 
    10. fw.write(bookname+' ('+authors+') ') 
    11. fw.write('- 您在位置 #'+allnotes[noteind]['noteHeading']['markPosition']+'-'+str(int(allnotes[noteind]['noteHeading']['markPosition'])+1)+' 的标注'+' | 添加于 '+Getnowdate()+' ') 
    12. fw.write(allnotes[noteind]['noteText'].replace(' ','')+' ') 
    13. fw.write('========== ') 
    14.  
    15. if (allnotes[noteind]['takenote']['note'].replace(' ','')+' ') not in existnotes: 
    16. fw.write(bookname+' ('+authors+') ') 
    17. fw.write('- 您在位置 #'+allnotes[noteind]['noteHeading']['markPosition']+' 的笔记'+' | 添加于 '+Getnowdate()+' ') 
    18. fw.write(allnotes[noteind]['takenote']['note']+' ') 
    19. fw.write('========== ')  
    20.  
    21. else: 
    22. if (allnotes[noteind]['noteText'].replace(' ','')+' ') not in existnotes: 
    23. fw.write(bookname+' ('+authors+') ') 
    24. fw.write('- 您在位置 #'+allnotes[noteind]['noteHeading']['markPosition']+'-'+str(int(allnotes[noteind]['noteHeading']['markPosition'])+1)+' 的标注'+' | 添加于 '+Getnowdate()+' ') 
    25. fw.write(allnotes[noteind]['noteText'].replace(' ','')+' ') 
    26. fw.write('========== ')  
    27. fw.close() 

    将读书笔记追加至My Clippings.txt
    将读书笔记追加至My Clippings.txt

    5.2适配成Variety箴言

    Variety是linux下的壁纸管理工具,具备使用本地文档显示箴言的功能,现将kindle笔记解析成Variety识别的格式,并展示出来,方便日常查看。

    1. #读入已做的笔记 
    2. #处理已添加的箴言 
    3. def Delline(line): 
    4. lastind=0 
    5. if '[' in line: 
    6. lastind=line.index('[') 
    7. return line[:lastind] 
    8.  
    9. existnotes=list(map(Delline,open('/home/wu/.config/variety/pluginconfig/quotes/qotes.txt','r').readlines())) 
    10.  
    11. #写入文件 
    12. fw=open('qotes.txt','w') 
    13. for noteind in range(0,len(allnotes)): 
    14. if allnotes[noteind]['noteText'].replace(' ','') not in existnotes: 
    15. fw.write(allnotes[noteind]['noteText'].replace(' ','')+'['+allnotes[noteind]['sectionHeading'].replace(' ','')+']'+'——'+bookname+' ('+authors+') ') 
    16. if allnotes[noteind]['takenote']['note'].replace(' ','')!='': 
    17. fw.write('#'+allnotes[noteind]['takenote']['note'].replace(' ','')+'——@'+'WuShaogui ') 
    18. fw.write('. ') 
    19. fw.close() 
    解析后的文档 Variety配置

    Variety箴言显示效果
    Variety箴言显示效果

    5.3匹配成anki笔记模式

    anki是背书神器,将kindle笔记导入anki中,可以对一本书的笔记进行反复的练习,加深感悟!

    1. #写入anki笔记导入格式 
    2. fw=open('%s-%s.txt'%(bookname,authors),'w') 
    3. for noteind in range(0,len(allnotes)): 
    4. fw.write(allnotes[noteind]['noteText'].replace(' ','')+' ' 
    5. +allnotes[noteind]['sectionHeading'].replace(' ','')+' ' 
    6. +bookname+' '+authors+' '+allnotes[noteind]['takenote']['note'].replace(' ','')+' ') 
    7. fw.close() 
    解析后的文档 Anki导入解析后文档
    文档导入后效果 最终效果图
  • 相关阅读:
    关于[x/y]一些小想法
    mycat主从读写分离范例
    EOJ 262 润清的烦恼
    mycat server.xml 配置文件详解
    Mongodb in Mycat指南
    牛客网NOIP赛前集训营-普及组(第一场)
    MyCAT分表初体验
    牛客网NOIP赛前集训营-提高组(第一场)
    日期类型的特殊性 -- 日期函数转换
    POJ 1966 Cable TV Network 【经典最小割问题】
  • 原文地址:https://www.cnblogs.com/wushaogui/p/12886324.html
Copyright © 2011-2022 走看看