掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 2553|回复: 8

[经验交流] 关于用Python脚本来快速批量制卡的一些经验分享

[复制链接]
  • TA的每日心情
    慵懒
    2021-9-1 08:46
  • 签到天数: 61 天

    [LV.6]常住居民II

    发表于 2021-2-19 07:28:36 | 显示全部楼层 |阅读模式
    本帖最后由 zhangchaont 于 2021-2-20 08:21 编辑 0 S0 p2 L/ r$ ^6 a, [

    3 T: [/ c% z- ?5 E/ X我从2013年接触Anki,刚开始觉得很难上手,中间还放弃了一段时间,这次重新开始使用是从去年的2月份,我开始用Anki来学习日语,虽然中间也走了一些弯路,但是这个让我坚持下来了,以前去外面报学习班几次也没有学下来。现在Anki已经成了我的日常,而在这个过程中,我也学会了一些和原来的目标不一样的东西,我最开始是想学英语,后来想学日语。虽然这两个目标目前的效果还行,我英文的词汇量大概3万不到,可以比较自如的阅读英文书籍,听语音书的话80%以上吧,虽然写和说还欠缺,但是也不是不能克服的。日语学了一年,N2的水平自测没有问题,N1的语法马上学完了。除了这两个之外,因为要使用Anki,我还折腾会了一些意想不到的东西,比如:Python,html,CSS等等。会写Python的简单代码是我觉得最爽的事情,它让我觉得我身边的那些不会编程的人就像哈里波特里面的麻瓜。我女儿上一年级之前已经学会了3000个汉字,现在看书已经没什么障碍了。
    ' o; M# z' p# ]. ^0 I1 _; a8 [& [' X% \
    Anki已经有这么多好用的插件了,在制卡方面有FastWordQuery,为什么我们还需要自己写代码呢?因为我们各自的需求是非常个性化的,而一个插件不可能完全满足你的要求,要完全让自己满意,那就只好自己折腾了。 最开始的时候,我经常会写邮件给WordQuery(FastWordQuery的前身)的作者,向他请教一些问题,但是那时Python也不怎么会,所以还是不得要领。后来我偶然在网上找了了一篇帖子:
    . ~7 W& |" |9 q  j# a/ Y. Nhttps://www.juliensobczak.com/wr ... anki-scripting.html. \% }* [# Q' p/ ~# B
    这个对我非常有启发,不过好像要翻墙才能看到。我打印成PDF了,感兴趣的朋友可以下下来看看。
    7 ~2 n  _- p+ M0 {  f6 W( ]后来我又在Anki的官方论坛里面提问,得到了Anki的作者Damien Elmes的指点,现在已经可以比较自如的用Python来制卡了。
    , J7 z- q9 n6 _' I4 T  _2 b- A
    ( M& j3 I; B& i" F, @/ R好了,闲话不多说,在这个帖子里面,我将演示如何通过Python代码来:
    ; S" v6 B9 Z* V, J# T" X! p1. 从百度汉语里面下载汉字的发音,解释词条等制成卡片;
    9 o* d( ?; X2 v9 b/ h1 d2. 从mdx词典文件里面将有需要的内容拿出来制成卡片;! M& T5 w' A1 ^+ U& ?( @& q
    3. 用Selenium从一些不能简单用requests库扒的网站上扒数据制成卡;
    3 g2 y( A5 \+ P& E1 B6 Y0 U; D5 S' Y9 E7 A" E
    首先请安装pycharm,这是一个非常好用的IDE,CE版本的是免费的,功能已经很全了。  F  M4 y* Q( f) Q
    " ]2 p5 M9 E& ~
    然后新建一个项目,名字随便,这里就叫anki-scripting吧。: s6 R- d5 z1 y' {* v3 b) o
    参照Anki的手册里面的指导https://addon-docs.ankiweb.net/#/getting-started$ j6 }2 E$ w6 }+ h: d( d  Y" Y
    在pycharm界面下方有一个console,点开就会出来Python的命令行解释器。" k# j$ b3 k3 g
    1. import subprocess% r/ e* j# ~# Q. B
    2. $ j7 A. ~9 o3 k
    3. subprocess.check_call(["pip3", "install", "--upgrade", "pip"])7 O% Z/ ~8 F% t% B6 m5 V& h( p7 x
    4. subprocess.check_call(["pip3", "install", "mypy", "aqt"])
    复制代码
    2 i' ~4 ^, C" Y, o( d- d/ i
    等安装完成,我们的准备工作就完成了,如果失败请自行搜索解决。下面的内容敬请期待,准备上班去了。$ h' b3 j. c- k

    ( J2 u) o( Y/ W$ J9 H0 Z" x+ y+ d' {; A( {2 [' _6 j

    7 L, z2 `/ q; m! l好了,在前面的准备工作的基础上,我们现在就可以来试着来用Python来操纵Anki了。9 m( p, O& T1 C! h' C
    5 u% Q6 l. L- P; v6 y# Q, V
    Anki的数据是保存在qlite3数据库里,在macOS上,路径是~/Library/Application Support/Anki2/username/collection.anki2,Windows的搜索一下。在用户名的文件夹下面,还有一个collection.media文件夹,这个里面保存的是媒体文件,MP3、图片之类的。" J7 L& B# ]2 T6 j+ }, T% |/ e
    1 k) Z& X% l3 j4 m
    下面我们可以点开PyCharm下面的Python Console。
    . y: _& ^+ J+ ^% x3 R
    1. from anki.collection import Collection
      1 b# ~. [6 R  d0 Y2 a; D
    2. col = Collection('path to your collection')
    复制代码

    + g3 s, H" ~- _$ p% q! u+ icollection.anki2文件的路径替换一下即可。这样我们就新建了一个collection的实例,注意,Anki软件要关掉。
    6 K9 ^- b; w$ X" I  V& O3 [7 l6 z- g下面我们来看看能用这个干嘛。& b" s  m+ y* z( K6 W
    1. # findNotes方法非常有用,查找的条件和你在Anki的浏览器里面是一样的,返回值是笔记的id号, 这里查找的条件是今天到期的笔记。4 ]" X  O: {$ C
    2. note_ids = col.findNotes('is:due')9 n! q. X9 W7 l+ U
    3. # 获取笔记% \; F' y1 N! H4 {9 G6 }  O0 Q3 n( b
    4. note = col.getNote(note_ids[0])
        r& P  r- D9 _7 K" s
    5. # items方法可以获取字段名和字段内容的元组
      0 @0 G7 q% p9 N
    6. print(note.items())& N5 w. m& V8 r
    7. # fields方法返回一个包含所有字段值的列表( G, ]. U. k9 h% c4 m
    8. print(note.fields())2 Z2 U& L. m9 Z' a! v; L: Y
    9. # model方法可以获取笔记的模板' g! t; N: R- Y4 _! v5 W/ T
    10. print(note.model())" w9 ~' B# l: Q0 M0 R3 |% W
    11. # 下面这条语句可以获取笔记的所有字段名
      0 L: v3 C2 T+ m/ c0 |. w; H( D
    12. print(col.models.fieldsNames(note.model())
    复制代码

      p( L6 S. A6 d9 F$ e$ J5 G( N6 m2 b
    6 n$ T5 o4 O+ N7 d* [
    ; E+ R4 v3 \0 U好的,下面我们来获取今天到期的卡片的第一字段里面的内容并打印出来。8 K/ n. G& W( z1 P3 j& E
    1. from anki.collection import Collection2 |( h! ^% H/ z! y* W
    2. col = Collection('path to your collection')
      + M" D& O2 Y$ P# g
    3. note_ids = col.findNotes('is:due')
      6 Q, V' b, F7 g* v4 p9 Y% o
    4. for nid in note_ids:% p$ s6 I2 ]+ s9 m
    5.     note = col.getNote(nid)
      ' n$ V0 P) V) `, D; y
    6.     key = note.items()[0][1]  Y- A8 t& t5 ?2 \0 E
    7.     print(key)
    复制代码
    " C5 E  @* j: c% ^; f# _8 U9 Z9 A3 A* b
    9 |. v# t  u# B7 J! b# \4 Q" ~
    你可能会想,我才不想列出这些呢,我是想修改卡片啊!!!!!别急,马上就到了。' ^4 q5 |9 a% n4 h! C

    " _" o  p4 t& G' q/ l& X
    1. # 在 获取了note对象以后,只需要几个操作就可以完成对卡片的修改
      , G( N0 I( y; `# v+ f& n- R" p. @1 i
    2. note['field_name'] = 'new value'
      9 ?2 K. D  W0 J  J
    3. note.flush()1 `, ]+ q6 ?! U! n! @
    4. col.save()
    复制代码
    ; g" m" Q% f; j& X# s
    ! j# x: j2 @6 q  ?+ ?
    现在你可以获取一个note对象,然后对它进行一点小小的修改,试试看。9 t3 Y% ]0 Z: {4 r2 D; j* _/ R
    * u+ m! v# R9 F) P# |; x
    ; H3 Q: S" K; R5 N1 Z$ F3 s4 Z
    7 J2 u  @" N; w) ~$ y( p9 P  n

    1 D6 a) B( G" c! M  c7 |下面来讲讲如何新建卡片,在Anki里,你点击新建的时候,会默认选择当前的deck,以及当前deck的默认卡片类型,在Python里面,我们首先需要搞定这个。
    ' I5 x8 G2 J( [: V8 p2 q5 F$ {; @
    " X5 T4 c0 j, r2 \; f
    1. # 下面有deck name 和 model name分别换成你要新建卡片的牌组名称和卡片类型名称        
      9 f4 K/ b* K7 ?7 C
    2. # select deck9 O4 A; o5 {) E' ]! b2 m
    3.         col.decks.select(col.decks.byName('deck name')['id'])& a, ?& v3 i) [/ S% a  H  \: M  U; `
    4. $ w8 n4 i0 r7 ?- o
    5.         # change current model
      - @7 k8 i* `# L" V
    6.         model = col.models.byName('model name')
      5 D$ E- H# z" M# x
    7.         cdeck = col.decks.current()
      6 T/ _! t3 c, U$ j  j
    8.         cdeck['mid'] = model['id']% o% n" u  S6 n
    9.         col.decks.save(cdeck)
    复制代码
    1 t! ]6 w; \/ q* V8 ~6 Q

    4 T  o( B6 w9 G0 _8 v1 A% A8 o2 J" Y7 w* P. I4 {
    这样我们就完成了选择牌组和卡片类型,下面就到了新建卡片了。
    4 V' I2 J/ D. ^5 ?) d
    1. note = col.newNote()( O( Q+ g/ y# l  N+ J% |2 p
    2. note.model()['did'] = col.decks.current()['id']4 i1 m6 l, @, p( o9 P; p! P4 Q* }
    3. note['field name'] = 'some value'
      $ r$ I9 V$ H5 ]
    4. col.addNote(note)6 f7 c5 I& U' B* P
    5. col.save()
      + n& s% ~. K- l6 f0 `! h& {
    6. col.close()
    复制代码
    0 U+ |: i5 P: G0 Q, f- y1 ?

    . m% h5 E0 q3 d! {3 e新建了一条笔记后,可以分别给各个字段赋值,然后用addNote方法添加到collection中,记得要用save来保存,最后要关闭collection。5 i9 O2 ?, e+ k8 R% M3 W
    - O* m% z4 m! A0 ?; o4 Z- B
    现在动手试试自己添加一条笔记吧。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?免费注册

    x

    评分

    2

    查看全部评分

    该用户从未签到

    发表于 2021-2-19 21:14:20 | 显示全部楼层
    楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。
  • TA的每日心情
    开心
    2022-1-5 10:27
  • 签到天数: 80 天

    [LV.6]常住居民II

    发表于 2021-2-20 09:32:48 | 显示全部楼层
    感谢分享,楼主辛苦了!
  • TA的每日心情
    慵懒
    2021-9-1 08:46
  • 签到天数: 61 天

    [LV.6]常住居民II

     楼主| 发表于 2021-2-20 16:53:33 | 显示全部楼层
    drongh 发表于 2021-2-19 21:14
    6 f# R4 d$ F) _& d6 h4 _楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。
    & f; t# f8 m) g5 p7 c* H9 Z

    / I1 R+ u- R$ \: M" v' p我还没有录过视频,下次试试
  • TA的每日心情
    开心
    2020-4-7 17:48
  • 签到天数: 201 天

    [LV.7]常住居民III

    发表于 2021-2-20 20:33:48 | 显示全部楼层
    LZ的思路是直接对ANKI存储卡片的数据库做直接操作呀,那确实相当灵活了。
  • TA的每日心情
    开心
    2020-2-20 10:47
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2022-5-5 18:55:40 | 显示全部楼层
    楼主牛人,谢谢教程
  • TA的每日心情
    无聊
    2022-6-23 21:02
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2022-5-6 23:00:19 | 显示全部楼层
    和anki有关的学习资料太少了。学习中
    您需要登录后才可以回帖 登录 | 免费注册

    本版积分规则

    小黑屋|手机版|Archiver|PDAWIKI |网站地图

    GMT+8, 2024-4-29 19:18 , Processed in 0.052350 second(s), 9 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

    快速回复 返回顶部 返回列表