掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 6215|回复: 8

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

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

    [LV.6]常住居民II

    发表于 2021-2-19 07:28:36 | 显示全部楼层 |阅读模式
    本帖最后由 zhangchaont 于 2021-2-20 08:21 编辑 ' e! v7 }; P- p0 V- k7 Y

    # ?. x6 P# o" Y  c& Y我从2013年接触Anki,刚开始觉得很难上手,中间还放弃了一段时间,这次重新开始使用是从去年的2月份,我开始用Anki来学习日语,虽然中间也走了一些弯路,但是这个让我坚持下来了,以前去外面报学习班几次也没有学下来。现在Anki已经成了我的日常,而在这个过程中,我也学会了一些和原来的目标不一样的东西,我最开始是想学英语,后来想学日语。虽然这两个目标目前的效果还行,我英文的词汇量大概3万不到,可以比较自如的阅读英文书籍,听语音书的话80%以上吧,虽然写和说还欠缺,但是也不是不能克服的。日语学了一年,N2的水平自测没有问题,N1的语法马上学完了。除了这两个之外,因为要使用Anki,我还折腾会了一些意想不到的东西,比如:Python,html,CSS等等。会写Python的简单代码是我觉得最爽的事情,它让我觉得我身边的那些不会编程的人就像哈里波特里面的麻瓜。我女儿上一年级之前已经学会了3000个汉字,现在看书已经没什么障碍了。
    $ Z# ?/ U) y' X+ s: k# _
    ) |3 W" m2 o2 PAnki已经有这么多好用的插件了,在制卡方面有FastWordQuery,为什么我们还需要自己写代码呢?因为我们各自的需求是非常个性化的,而一个插件不可能完全满足你的要求,要完全让自己满意,那就只好自己折腾了。 最开始的时候,我经常会写邮件给WordQuery(FastWordQuery的前身)的作者,向他请教一些问题,但是那时Python也不怎么会,所以还是不得要领。后来我偶然在网上找了了一篇帖子:. Y" a& _, s4 ?- {" w3 k
    https://www.juliensobczak.com/wr ... anki-scripting.html
    ( K/ p% {$ X+ d# q6 Y* Z+ y这个对我非常有启发,不过好像要翻墙才能看到。我打印成PDF了,感兴趣的朋友可以下下来看看。
    9 ~% o/ x# t. Y后来我又在Anki的官方论坛里面提问,得到了Anki的作者Damien Elmes的指点,现在已经可以比较自如的用Python来制卡了。
    8 v. c' G6 b& U6 W6 T- d* W: \1 S
    好了,闲话不多说,在这个帖子里面,我将演示如何通过Python代码来:- C: Q+ Y7 L+ v; |$ e7 E
    1. 从百度汉语里面下载汉字的发音,解释词条等制成卡片;3 D  s1 t7 _% a. M3 H
    2. 从mdx词典文件里面将有需要的内容拿出来制成卡片;
    - X8 |6 [$ v& n, ?3. 用Selenium从一些不能简单用requests库扒的网站上扒数据制成卡;! k- D% z% `7 C* V
    6 V( G+ h* ?7 L7 u  e
    首先请安装pycharm,这是一个非常好用的IDE,CE版本的是免费的,功能已经很全了。5 w7 x; y) t% C. s' Y4 |
    7 u0 i; N( h  Z$ j
    然后新建一个项目,名字随便,这里就叫anki-scripting吧。5 z- t7 C, g* e" W0 \/ O2 d+ A, w
    参照Anki的手册里面的指导https://addon-docs.ankiweb.net/#/getting-started1 M5 \; N& W! A. J
    在pycharm界面下方有一个console,点开就会出来Python的命令行解释器。
    & v) F  H' N& R( |$ c1 _# }
    1. import subprocess
      * }8 `& U; G1 T" a

    2. $ V, k7 s+ ?' v* d2 q
    3. subprocess.check_call(["pip3", "install", "--upgrade", "pip"])
      4 ^. @4 ]- F; J3 p$ n' \) H2 S
    4. subprocess.check_call(["pip3", "install", "mypy", "aqt"])
    复制代码
    # Q/ A: M5 V3 `9 D4 v" M4 L
    等安装完成,我们的准备工作就完成了,如果失败请自行搜索解决。下面的内容敬请期待,准备上班去了。
    4 Q+ j' V6 i7 I/ C3 c
    ! ]7 [0 U1 r& a8 R
    2 K) B* o. U% }+ o& v, A& h% V- i  \0 v, r- P7 K
    好了,在前面的准备工作的基础上,我们现在就可以来试着来用Python来操纵Anki了。7 N/ l' s7 W, U0 b+ w

    2 n: [3 z) H2 ~3 YAnki的数据是保存在qlite3数据库里,在macOS上,路径是~/Library/Application Support/Anki2/username/collection.anki2,Windows的搜索一下。在用户名的文件夹下面,还有一个collection.media文件夹,这个里面保存的是媒体文件,MP3、图片之类的。
    6 a: D; R, f7 e. P, A% ?7 G) S
    , ^, P" c6 N) B* E6 \- n下面我们可以点开PyCharm下面的Python Console。
    , [- U" r, g' u8 j2 R  o6 c
    1. from anki.collection import Collection
      ) D8 I$ }' `" y8 Y: [% x0 l% u$ Z
    2. col = Collection('path to your collection')
    复制代码
    # y/ ^7 O* M8 W' l* ]
    collection.anki2文件的路径替换一下即可。这样我们就新建了一个collection的实例,注意,Anki软件要关掉。
    4 h7 p$ `+ Q  H. k9 ]# A- g下面我们来看看能用这个干嘛。7 Y% b, V. @+ g# p8 r! R
    1. # findNotes方法非常有用,查找的条件和你在Anki的浏览器里面是一样的,返回值是笔记的id号, 这里查找的条件是今天到期的笔记。
      2 Y' i; ^* g/ S& r& a4 U( X
    2. note_ids = col.findNotes('is:due')$ \- x8 Q1 Q% n" w
    3. # 获取笔记$ _5 G0 i/ p6 a
    4. note = col.getNote(note_ids[0])5 y' _' h+ O# E/ A
    5. # items方法可以获取字段名和字段内容的元组; ~* d% ?' y" w. I; ~( x* T8 e: v
    6. print(note.items())
      - g+ ?& Q8 W: w. _/ \, X1 G
    7. # fields方法返回一个包含所有字段值的列表$ D9 R, b. N+ V- K$ k6 H! Z
    8. print(note.fields())3 q5 I: q4 o  ?( t! S
    9. # model方法可以获取笔记的模板
      5 g' I7 ]! S% C: ^
    10. print(note.model())- }% a/ n: R4 s
    11. # 下面这条语句可以获取笔记的所有字段名
      - i4 [# h# f5 x! p8 p+ G
    12. print(col.models.fieldsNames(note.model())
    复制代码

    8 X( F1 t" W8 w, x4 F. J, q& S: ~! ]: d6 j* `$ P

    8 n! ^3 J% P: G; e- Q好的,下面我们来获取今天到期的卡片的第一字段里面的内容并打印出来。
    # F; E0 s! Q. t4 R9 u$ ?
    1. from anki.collection import Collection
      1 a# b, t0 M8 M" _. h
    2. col = Collection('path to your collection')
      ; L! ~4 `$ P, ]6 O
    3. note_ids = col.findNotes('is:due')
      2 `, a) O! U& q& q" H9 t
    4. for nid in note_ids:( o+ a) Y: C& ]5 T
    5.     note = col.getNote(nid)
      , E+ E, i$ A1 u. ?5 I
    6.     key = note.items()[0][1]
      + s: j& m4 o" n2 {, i& U
    7.     print(key)
    复制代码

    * l( G: i( Y, I0 m5 w9 c) ~7 a0 W1 V: W* ]3 [0 \
    你可能会想,我才不想列出这些呢,我是想修改卡片啊!!!!!别急,马上就到了。
    0 L3 I% p7 e8 H6 K
    * ]( }# d6 p7 R7 z/ _
    1. # 在 获取了note对象以后,只需要几个操作就可以完成对卡片的修改
        o5 F8 \" J) _% }0 l( ^# n% z- P
    2. note['field_name'] = 'new value'9 f: J8 s; v+ w) w
    3. note.flush()
      4 t% ?# f0 M* H/ H$ H4 `
    4. col.save()
    复制代码

    * R  ~' ]' K. v2 u' u! l" |8 N
    / ?4 x+ C$ F. n. t: S3 @6 a+ t; l现在你可以获取一个note对象,然后对它进行一点小小的修改,试试看。
    8 r7 E9 n; z& p% _- t0 T7 X5 N, O& O: s# f  B  f# f& B
    ( Z0 I" }6 \3 Z( N! q

    ; S7 o' _# G1 j7 m% |1 O$ x, A. {
    5 s' ^' b: n+ ?下面来讲讲如何新建卡片,在Anki里,你点击新建的时候,会默认选择当前的deck,以及当前deck的默认卡片类型,在Python里面,我们首先需要搞定这个。
    6 o, S5 J# E, e8 }' `$ M8 K% V
    2 |& L  k4 u7 Q) e$ }, l
    1. # 下面有deck name 和 model name分别换成你要新建卡片的牌组名称和卡片类型名称        9 {6 t# K: M( d, K9 a
    2. # select deck. k! X8 X7 T/ F
    3.         col.decks.select(col.decks.byName('deck name')['id'])0 g2 B, j/ V7 Q8 A5 z

    4. 5 a1 ^# `; g6 o; h6 A$ h
    5.         # change current model9 d/ b  ?. I- }
    6.         model = col.models.byName('model name')& y9 c$ U* F* i# \. z3 \9 Z' v- b3 @
    7.         cdeck = col.decks.current()
        }( T, i, a4 d1 Y0 I' D, G
    8.         cdeck['mid'] = model['id']
      - f6 L7 b. ]3 z6 U* R6 \& ?/ A
    9.         col.decks.save(cdeck)
    复制代码

    / n. e. j+ i6 F2 Q; R9 E8 T1 m2 Y$ U2 V8 A& s. L  X  T

    ; `+ K+ B# S% @! w/ P0 ~  S这样我们就完成了选择牌组和卡片类型,下面就到了新建卡片了。5 S& S  E  R- x; V$ X7 z
    1. note = col.newNote()" r1 |- ], ^8 G
    2. note.model()['did'] = col.decks.current()['id']
      + D: l$ y# g. f9 J. l
    3. note['field name'] = 'some value'4 V+ w) ?" w: E0 R8 w+ ^; d; G
    4. col.addNote(note)5 Y: g6 Z/ s0 w( A
    5. col.save()
      % @$ q8 k* P* u2 r/ i# }) x4 r! @
    6. col.close()
    复制代码

    " J1 l% O0 j% m! i- ]- H9 m6 G9 m8 T2 x. r$ p+ A
    新建了一条笔记后,可以分别给各个字段赋值,然后用addNote方法添加到collection中,记得要用save来保存,最后要关闭collection。/ |3 T+ q7 ~# X* m2 R# `
    3 _2 y, j* i5 n% }
    现在动手试试自己添加一条笔记吧。

    本帖子中包含更多资源

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

    x

    评分

    2

    查看全部评分

    该用户从未签到

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

    [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
    8 \1 |  ]& H6 W楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。
    : j: e' i, r- k% n" D  p- d

    " J) m+ M& T& @4 L我还没有录过视频,下次试试
  • 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, 2026-10-24 17:02 , Processed in 1.612641 second(s), 26 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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