掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 2555|回复: 8

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

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

    [LV.6]常住居民II

    发表于 2021-2-19 07:28:36 | 显示全部楼层 |阅读模式
    本帖最后由 zhangchaont 于 2021-2-20 08:21 编辑 $ Q% a$ }: `; s5 ]6 n
    % Y% I" ^; ~  Z2 b
    我从2013年接触Anki,刚开始觉得很难上手,中间还放弃了一段时间,这次重新开始使用是从去年的2月份,我开始用Anki来学习日语,虽然中间也走了一些弯路,但是这个让我坚持下来了,以前去外面报学习班几次也没有学下来。现在Anki已经成了我的日常,而在这个过程中,我也学会了一些和原来的目标不一样的东西,我最开始是想学英语,后来想学日语。虽然这两个目标目前的效果还行,我英文的词汇量大概3万不到,可以比较自如的阅读英文书籍,听语音书的话80%以上吧,虽然写和说还欠缺,但是也不是不能克服的。日语学了一年,N2的水平自测没有问题,N1的语法马上学完了。除了这两个之外,因为要使用Anki,我还折腾会了一些意想不到的东西,比如:Python,html,CSS等等。会写Python的简单代码是我觉得最爽的事情,它让我觉得我身边的那些不会编程的人就像哈里波特里面的麻瓜。我女儿上一年级之前已经学会了3000个汉字,现在看书已经没什么障碍了。) O' g! q7 D" m& M7 X8 i4 H/ S* k

    ) ?2 z; ?) g8 X& IAnki已经有这么多好用的插件了,在制卡方面有FastWordQuery,为什么我们还需要自己写代码呢?因为我们各自的需求是非常个性化的,而一个插件不可能完全满足你的要求,要完全让自己满意,那就只好自己折腾了。 最开始的时候,我经常会写邮件给WordQuery(FastWordQuery的前身)的作者,向他请教一些问题,但是那时Python也不怎么会,所以还是不得要领。后来我偶然在网上找了了一篇帖子:- |8 Y: |) G, G& ^) j
    https://www.juliensobczak.com/wr ... anki-scripting.html" Z* {; T, p  [; ~# |
    这个对我非常有启发,不过好像要翻墙才能看到。我打印成PDF了,感兴趣的朋友可以下下来看看。8 Q; A! i& p- o( x! y" B
    后来我又在Anki的官方论坛里面提问,得到了Anki的作者Damien Elmes的指点,现在已经可以比较自如的用Python来制卡了。
    - s8 G7 C8 D1 z# S- T( l7 F
    0 y/ S+ p/ l. }- _好了,闲话不多说,在这个帖子里面,我将演示如何通过Python代码来:
    5 S. X9 r( B% v8 v8 D5 W4 ?; h+ d1. 从百度汉语里面下载汉字的发音,解释词条等制成卡片;' F# ]4 A8 P( V
    2. 从mdx词典文件里面将有需要的内容拿出来制成卡片;  N0 S8 H; `: Q
    3. 用Selenium从一些不能简单用requests库扒的网站上扒数据制成卡;- h" A+ t6 Q" A6 t1 E
    * @9 d" H  s$ O" r" w* Q4 |
    首先请安装pycharm,这是一个非常好用的IDE,CE版本的是免费的,功能已经很全了。( B, A8 v0 X: a3 Q) I! ^
    3 j1 `) J% i% `* b' O1 \1 s
    然后新建一个项目,名字随便,这里就叫anki-scripting吧。
      v/ ~" b2 @% t4 n* {) K参照Anki的手册里面的指导https://addon-docs.ankiweb.net/#/getting-started  t! J6 Q3 X2 i- r7 v
    在pycharm界面下方有一个console,点开就会出来Python的命令行解释器。* d7 C  `8 Z% Y8 ~9 d6 F! q
    1. import subprocess
      . ]5 H5 M& F$ A! E" J

    2. * B* `4 @. c( d
    3. subprocess.check_call(["pip3", "install", "--upgrade", "pip"])
      ; e7 B" z$ k# P. C  ?# y3 y
    4. subprocess.check_call(["pip3", "install", "mypy", "aqt"])
    复制代码

    : F3 Z" P+ I' j3 u- A3 r" ^% o+ ]等安装完成,我们的准备工作就完成了,如果失败请自行搜索解决。下面的内容敬请期待,准备上班去了。' G* ~8 N& o7 J6 m) [6 v
    + y: t1 ?) l2 n3 Y# h% a: [

    8 S) m! S# V: V6 N# `; T' F+ ?  B% j" ?( N( E' v( ]
    好了,在前面的准备工作的基础上,我们现在就可以来试着来用Python来操纵Anki了。2 m6 k& ~3 |9 v; @
    ; W$ X+ y9 w. q5 b* X1 j
    Anki的数据是保存在qlite3数据库里,在macOS上,路径是~/Library/Application Support/Anki2/username/collection.anki2,Windows的搜索一下。在用户名的文件夹下面,还有一个collection.media文件夹,这个里面保存的是媒体文件,MP3、图片之类的。
    ! J0 [1 l! v! D( l, ]# x! ~& C/ X; O3 I: c# a
    下面我们可以点开PyCharm下面的Python Console。
    : ~2 M; G1 a3 ?% M& ~
    1. from anki.collection import Collection6 M. f: {0 d( e5 }& [8 q
    2. col = Collection('path to your collection')
    复制代码

    ' u6 Z1 p$ P& _# R9 ]# vcollection.anki2文件的路径替换一下即可。这样我们就新建了一个collection的实例,注意,Anki软件要关掉。" j  v, e- u8 ~0 n* K
    下面我们来看看能用这个干嘛。1 q$ d7 ^+ v# b* Z0 `- y
    1. # findNotes方法非常有用,查找的条件和你在Anki的浏览器里面是一样的,返回值是笔记的id号, 这里查找的条件是今天到期的笔记。9 _4 `! `& M# K" R( Z- c0 `# \+ `* G
    2. note_ids = col.findNotes('is:due')
      3 }8 d. a3 l' o/ _% f, i
    3. # 获取笔记: \: z  ?2 F  v, B/ h% a2 C  c
    4. note = col.getNote(note_ids[0])
      " {/ o; R7 Q4 E; z/ ~! n* F  C
    5. # items方法可以获取字段名和字段内容的元组) A4 f8 E9 d7 F1 L2 a
    6. print(note.items())3 J1 L8 q+ x* J. H6 v: ^( Y% E
    7. # fields方法返回一个包含所有字段值的列表% N+ d. U- U$ _
    8. print(note.fields())
      ; q* w- N, z# ~: Z2 F
    9. # model方法可以获取笔记的模板
      ) n9 j( y* E! Q9 K. S8 V. z6 v
    10. print(note.model())
      , `$ Q: s: d; x* v
    11. # 下面这条语句可以获取笔记的所有字段名2 f; d; N* M0 ~( l5 p4 {
    12. print(col.models.fieldsNames(note.model())
    复制代码
    , w* V6 K2 u# t. |

    " e4 t9 {4 {' X  c  Q4 N
    # G% x5 n' n1 q; c- L. r好的,下面我们来获取今天到期的卡片的第一字段里面的内容并打印出来。$ E: n7 ?$ ^/ w9 M8 h8 f
    1. from anki.collection import Collection
      $ {4 ~* N# ^: t+ }
    2. col = Collection('path to your collection')
      % @/ B+ @* ^5 v. `" G
    3. note_ids = col.findNotes('is:due')7 C3 m& @" i9 g  L2 ^5 `, q9 H. }
    4. for nid in note_ids:
      # Z1 k( R4 W/ k7 D( ~( |
    5.     note = col.getNote(nid)7 M9 r1 y  o0 z1 K. P8 o: e
    6.     key = note.items()[0][1]! a6 P( T; \* `
    7.     print(key)
    复制代码

    ( \" C% b) C" `, P
    # f7 m: w! D3 F; \7 ~4 D你可能会想,我才不想列出这些呢,我是想修改卡片啊!!!!!别急,马上就到了。
    ( E6 o, v/ l8 m  b( o2 l: `9 U/ i7 i( A+ _
    1. # 在 获取了note对象以后,只需要几个操作就可以完成对卡片的修改  ?; R! c: i+ b' c
    2. note['field_name'] = 'new value'3 g( d' f. a) ?; `/ r6 i
    3. note.flush()
      4 n3 z$ O  T& ~) m+ l
    4. col.save()
    复制代码
    5 s% G; p, A6 V* v, V7 `

    $ y1 T: H; s1 ~3 F- n" W, I现在你可以获取一个note对象,然后对它进行一点小小的修改,试试看。
    0 I' J; E* K' x: T8 H: S
    * ^1 T. F# x2 L* Q' y& j) x" E' P$ v5 m) z, ~' s6 I; H4 J

    ( Y# }4 ?0 O8 D- c9 r, v6 @4 q9 [8 n: l' m9 X* U
    下面来讲讲如何新建卡片,在Anki里,你点击新建的时候,会默认选择当前的deck,以及当前deck的默认卡片类型,在Python里面,我们首先需要搞定这个。, K' |8 q" m) _, m
    ) }3 a) U4 N, R0 T
    1. # 下面有deck name 和 model name分别换成你要新建卡片的牌组名称和卡片类型名称        " \7 }' y( t" ?0 k
    2. # select deck
      % o& v3 m, K4 ^' T# [* L# N% S5 f
    3.         col.decks.select(col.decks.byName('deck name')['id'])( ^- P2 s% p) G1 w& x1 ]$ o; ]9 O5 p
    4. 1 X5 I- }9 x, c2 D
    5.         # change current model% r' L6 n% R" r. R* Z# p: h
    6.         model = col.models.byName('model name')
      / d' R' w: I. f( z2 N' X6 A# t+ }4 U
    7.         cdeck = col.decks.current()
      6 ?7 l8 e- t- g! g; G2 c
    8.         cdeck['mid'] = model['id']
      0 z9 a! B1 O8 @' @
    9.         col.decks.save(cdeck)
    复制代码
    , Q$ c8 C' I) u$ b% m8 W. F3 g

    8 j% e9 B: f: }, u5 h9 Q' E2 r. k. |! t; C) T" d# O# q
    这样我们就完成了选择牌组和卡片类型,下面就到了新建卡片了。$ D( ]; |7 R0 |) \" T
    1. note = col.newNote()
      ' q+ D# J4 _) D
    2. note.model()['did'] = col.decks.current()['id']
      ) S9 M$ e  \/ ]( |. R& [
    3. note['field name'] = 'some value'9 Q- i2 L0 o; s2 v# A1 D5 T7 M- m- d  v
    4. col.addNote(note)% V! \2 `) |$ X1 k
    5. col.save()) F4 |4 S5 }2 P2 U( {
    6. col.close()
    复制代码
    ! L; _7 p0 f5 k3 S# C. `

    : M0 Y; d" n; Y9 `& h* s) E新建了一条笔记后,可以分别给各个字段赋值,然后用addNote方法添加到collection中,记得要用save来保存,最后要关闭collection。
      X8 s: b' C; W4 `! O5 o# ~9 L0 E- u# J) m
    现在动手试试自己添加一条笔记吧。

    本帖子中包含更多资源

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

    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+ e* x7 U8 D9 r
    楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。

    : q- I, m8 u( C0 [# r' Q8 Z9 a7 u# c8 [3 C
    我还没有录过视频,下次试试
  • 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-30 00:02 , Processed in 0.053659 second(s), 9 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

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