掌上百科 - PDAWIKI

用户名  找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 4726|回复: 8

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

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

    [LV.6]常住居民II

    发表于 2021-2-19 07:28:36 | 显示全部楼层 |阅读模式
    本帖最后由 zhangchaont 于 2021-2-20 08:21 编辑
    3 H* c: G6 N9 M' _( d! ?% z- R: \. q
    我从2013年接触Anki,刚开始觉得很难上手,中间还放弃了一段时间,这次重新开始使用是从去年的2月份,我开始用Anki来学习日语,虽然中间也走了一些弯路,但是这个让我坚持下来了,以前去外面报学习班几次也没有学下来。现在Anki已经成了我的日常,而在这个过程中,我也学会了一些和原来的目标不一样的东西,我最开始是想学英语,后来想学日语。虽然这两个目标目前的效果还行,我英文的词汇量大概3万不到,可以比较自如的阅读英文书籍,听语音书的话80%以上吧,虽然写和说还欠缺,但是也不是不能克服的。日语学了一年,N2的水平自测没有问题,N1的语法马上学完了。除了这两个之外,因为要使用Anki,我还折腾会了一些意想不到的东西,比如:Python,html,CSS等等。会写Python的简单代码是我觉得最爽的事情,它让我觉得我身边的那些不会编程的人就像哈里波特里面的麻瓜。我女儿上一年级之前已经学会了3000个汉字,现在看书已经没什么障碍了。
    9 y- g( Y( {( O% c& _+ ]. ^6 E& f. f
    / K8 L: D, J/ S' z6 GAnki已经有这么多好用的插件了,在制卡方面有FastWordQuery,为什么我们还需要自己写代码呢?因为我们各自的需求是非常个性化的,而一个插件不可能完全满足你的要求,要完全让自己满意,那就只好自己折腾了。 最开始的时候,我经常会写邮件给WordQuery(FastWordQuery的前身)的作者,向他请教一些问题,但是那时Python也不怎么会,所以还是不得要领。后来我偶然在网上找了了一篇帖子:  k3 z) p2 l, c- V: n
    https://www.juliensobczak.com/wr ... anki-scripting.html
    9 i/ ~3 s' ~4 `6 R$ i这个对我非常有启发,不过好像要翻墙才能看到。我打印成PDF了,感兴趣的朋友可以下下来看看。
    ' ?, _6 X& I  c$ K( a后来我又在Anki的官方论坛里面提问,得到了Anki的作者Damien Elmes的指点,现在已经可以比较自如的用Python来制卡了。3 R, l2 t# m- B3 }
    ( P) R, e, o, ?0 c* ?( q
    好了,闲话不多说,在这个帖子里面,我将演示如何通过Python代码来:# ]# M# r5 X$ K7 H) f) B* q# w
    1. 从百度汉语里面下载汉字的发音,解释词条等制成卡片;" g2 t0 T! y  W6 L- @
    2. 从mdx词典文件里面将有需要的内容拿出来制成卡片;5 P$ Q' Q& w7 ~( J
    3. 用Selenium从一些不能简单用requests库扒的网站上扒数据制成卡;
    ! q3 n: i4 R* t( h$ \- P2 l" d0 F. z$ V! F' R  S$ v& J
    首先请安装pycharm,这是一个非常好用的IDE,CE版本的是免费的,功能已经很全了。8 Y7 O* O3 j8 c$ w
    7 z" l9 N' a3 K9 V8 h3 m+ k4 H
    然后新建一个项目,名字随便,这里就叫anki-scripting吧。3 [+ E7 M1 F8 C. `$ ]% i- J
    参照Anki的手册里面的指导https://addon-docs.ankiweb.net/#/getting-started
    # @0 v( u8 v- z9 c/ R' q3 n; y在pycharm界面下方有一个console,点开就会出来Python的命令行解释器。. H( c# l/ e( c! g: r
    1. import subprocess, c& q3 Q3 E0 Z0 O$ a
    2. ( o9 J9 @1 x# s9 G
    3. subprocess.check_call(["pip3", "install", "--upgrade", "pip"])& l+ o' D$ N* w, i! I
    4. subprocess.check_call(["pip3", "install", "mypy", "aqt"])
    复制代码

    $ _/ r2 m, ^! r& Q, x等安装完成,我们的准备工作就完成了,如果失败请自行搜索解决。下面的内容敬请期待,准备上班去了。1 ~$ [9 U( d% |! R! X* `9 K
    - P$ M4 c5 F+ l6 i

    1 D, p2 S, ~* s: |* a( s$ E" ^# H7 j: ?. q* @( P
    好了,在前面的准备工作的基础上,我们现在就可以来试着来用Python来操纵Anki了。
    8 s& @4 P5 h  H, Y% P6 F0 g% ^* K9 X( M& n2 b& g$ P
    Anki的数据是保存在qlite3数据库里,在macOS上,路径是~/Library/Application Support/Anki2/username/collection.anki2,Windows的搜索一下。在用户名的文件夹下面,还有一个collection.media文件夹,这个里面保存的是媒体文件,MP3、图片之类的。
    + H8 b" W% s+ j8 T0 v& b
    $ i: L& c( d3 g- ~8 `2 q% L# E下面我们可以点开PyCharm下面的Python Console。4 Z2 W" y$ v' [& g) i
    1. from anki.collection import Collection# S6 V( Q' y; U3 b
    2. col = Collection('path to your collection')
    复制代码
    3 ?5 v* O& a8 |6 b- W$ \
    collection.anki2文件的路径替换一下即可。这样我们就新建了一个collection的实例,注意,Anki软件要关掉。9 R4 r5 Z' N+ }4 t& U
    下面我们来看看能用这个干嘛。+ @8 ^. P: E: i
    1. # findNotes方法非常有用,查找的条件和你在Anki的浏览器里面是一样的,返回值是笔记的id号, 这里查找的条件是今天到期的笔记。! f* j; ]4 y- E* d$ i% Y* K
    2. note_ids = col.findNotes('is:due')
      $ ~& v5 [. m0 N
    3. # 获取笔记
      : A" V( U; L. L' q$ k% ?( Q* D
    4. note = col.getNote(note_ids[0])
      " q) Z4 W3 |& |% q% y& E
    5. # items方法可以获取字段名和字段内容的元组' _0 q3 o) Y& b+ R
    6. print(note.items())
      0 {. T- W$ x  L" x' M- ?8 E$ X  {
    7. # fields方法返回一个包含所有字段值的列表# d! Z, U& Z6 j7 e: ^. R
    8. print(note.fields())/ u+ k, t4 l; B* W8 I% |
    9. # model方法可以获取笔记的模板5 N8 T- G, U. t' y  i
    10. print(note.model())7 {2 p9 ^% N9 I" h- V  A+ Q/ O
    11. # 下面这条语句可以获取笔记的所有字段名# ]5 ~! K) f5 i
    12. print(col.models.fieldsNames(note.model())
    复制代码

    0 P! J6 z, A2 s) w( K, y
    ( G% t' X2 g  k) l6 G6 ]% o3 r' f5 V6 |/ N( r7 _- u$ v4 N, {
    好的,下面我们来获取今天到期的卡片的第一字段里面的内容并打印出来。
    % Z5 y) U8 }# `4 Q6 w* j
    1. from anki.collection import Collection
      2 K$ g! r" e0 j! [: s5 z% p
    2. col = Collection('path to your collection'); O- ^8 b& W8 K! I. x
    3. note_ids = col.findNotes('is:due')
      , {6 V# n5 I( O4 O9 i3 C) x
    4. for nid in note_ids:" @7 P  F% C" Q! o, i
    5.     note = col.getNote(nid)+ M7 j- M  r9 z% c# P( Y" R1 _
    6.     key = note.items()[0][1]. N" Q' \- n% f  L  r/ c
    7.     print(key)
    复制代码
    7 p7 E% _; L, D3 r0 ?

    ; l$ x4 W  b5 i6 e: Z& d0 s你可能会想,我才不想列出这些呢,我是想修改卡片啊!!!!!别急,马上就到了。
      e( n3 [+ D, ^8 G" D$ v, I
    ! E1 U( g: s6 o
    1. # 在 获取了note对象以后,只需要几个操作就可以完成对卡片的修改
      6 G' `0 m6 {& E' S9 E  S- y
    2. note['field_name'] = 'new value'
      9 ~, G% b; A; c% Y" k4 H
    3. note.flush()
      ; K6 e$ M' D3 r6 g/ b% A
    4. col.save()
    复制代码

    - l* |0 w4 ~9 X7 x" |4 r& v6 H9 L& s4 M, d" _
    现在你可以获取一个note对象,然后对它进行一点小小的修改,试试看。
    4 G- u' L) W6 e' y
    1 n" _9 P% z% Y2 R# }5 v' h) K- t- Z" m8 p- ~2 |

      _% B& p/ m9 D% I' S* h8 _
    2 C6 V( L5 z; j2 a: G% ]& d下面来讲讲如何新建卡片,在Anki里,你点击新建的时候,会默认选择当前的deck,以及当前deck的默认卡片类型,在Python里面,我们首先需要搞定这个。
    ! X: e- \" Q- R2 ~' d$ o7 _( h" r9 c- g9 \" y. L4 \& L  M
    1. # 下面有deck name 和 model name分别换成你要新建卡片的牌组名称和卡片类型名称        0 [$ X( C: V9 k0 e. M
    2. # select deck- ]( {) j; M* k6 i: \4 a
    3.         col.decks.select(col.decks.byName('deck name')['id']); b6 u" I( a1 ^6 `- |
    4. 2 A! b( q! n2 D( t' ^
    5.         # change current model' u+ K5 k" O6 y6 G* E
    6.         model = col.models.byName('model name')
      $ ?$ y& e: S6 G& W1 M% m
    7.         cdeck = col.decks.current()
      0 _0 Z4 {. \3 R  R3 D
    8.         cdeck['mid'] = model['id']
      . @1 E2 |/ }/ v: G2 X
    9.         col.decks.save(cdeck)
    复制代码

    , E' R+ ~, W9 ]  _0 U
    ' Y* {8 F6 p; _/ v/ v  N; b7 W0 R, S+ A( r- _# Z
    这样我们就完成了选择牌组和卡片类型,下面就到了新建卡片了。
    & [: G' \' g: s4 J1 }5 T- L! e
    1. note = col.newNote()
      5 q% y1 l0 M1 f( W* D
    2. note.model()['did'] = col.decks.current()['id']
      % Y9 F2 E; y9 ~# F
    3. note['field name'] = 'some value'
      9 H' e; t8 {! V* b: e+ H
    4. col.addNote(note)9 _8 ?, T& K9 l$ s
    5. col.save()
      ! ~6 z1 B9 b% A  f4 N. Q  G
    6. col.close()
    复制代码

    4 T& `3 o$ P+ Q% f/ A
    9 q6 l8 S1 h5 N新建了一条笔记后,可以分别给各个字段赋值,然后用addNote方法添加到collection中,记得要用save来保存,最后要关闭collection。  }7 b) `; ?5 r8 J3 a% j. `
    + y1 F* h* }+ B: N5 Y
    现在动手试试自己添加一条笔记吧。

    本帖子中包含更多资源

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

    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( U5 |0 E/ Q0 |4 k$ u+ z( D: k
    楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。

    3 T  p) @! B- i: s
    ( \- G' q% r8 O# Q  T4 z; k; U我还没有录过视频,下次试试
  • 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, 2025-5-20 04:21 , Processed in 0.021395 second(s), 23 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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