掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 4689|回复: 8

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

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

    [LV.6]常住居民II

    发表于 2021-2-19 07:28:36 | 显示全部楼层 |阅读模式
    本帖最后由 zhangchaont 于 2021-2-20 08:21 编辑
    : l* \( E0 ^! k* `
    : |4 Y0 o2 o( M/ c/ s1 v4 b我从2013年接触Anki,刚开始觉得很难上手,中间还放弃了一段时间,这次重新开始使用是从去年的2月份,我开始用Anki来学习日语,虽然中间也走了一些弯路,但是这个让我坚持下来了,以前去外面报学习班几次也没有学下来。现在Anki已经成了我的日常,而在这个过程中,我也学会了一些和原来的目标不一样的东西,我最开始是想学英语,后来想学日语。虽然这两个目标目前的效果还行,我英文的词汇量大概3万不到,可以比较自如的阅读英文书籍,听语音书的话80%以上吧,虽然写和说还欠缺,但是也不是不能克服的。日语学了一年,N2的水平自测没有问题,N1的语法马上学完了。除了这两个之外,因为要使用Anki,我还折腾会了一些意想不到的东西,比如:Python,html,CSS等等。会写Python的简单代码是我觉得最爽的事情,它让我觉得我身边的那些不会编程的人就像哈里波特里面的麻瓜。我女儿上一年级之前已经学会了3000个汉字,现在看书已经没什么障碍了。
    0 x+ Q! c/ h( D, T
    6 S- @, ?) M& }" jAnki已经有这么多好用的插件了,在制卡方面有FastWordQuery,为什么我们还需要自己写代码呢?因为我们各自的需求是非常个性化的,而一个插件不可能完全满足你的要求,要完全让自己满意,那就只好自己折腾了。 最开始的时候,我经常会写邮件给WordQuery(FastWordQuery的前身)的作者,向他请教一些问题,但是那时Python也不怎么会,所以还是不得要领。后来我偶然在网上找了了一篇帖子:
    " q- x7 V9 I& w5 {+ F8 M: s4 ghttps://www.juliensobczak.com/wr ... anki-scripting.html6 e! i7 Z4 a# N8 j- w) V
    这个对我非常有启发,不过好像要翻墙才能看到。我打印成PDF了,感兴趣的朋友可以下下来看看。. t! j# A3 }* M1 Q% {$ q7 @
    后来我又在Anki的官方论坛里面提问,得到了Anki的作者Damien Elmes的指点,现在已经可以比较自如的用Python来制卡了。7 ]/ F# e2 ~7 g$ Y2 ~% D' z

    . J9 p: W/ E) R9 U8 r' i好了,闲话不多说,在这个帖子里面,我将演示如何通过Python代码来:& a6 y: @+ W! A) N/ [6 w" ?! q2 `  V
    1. 从百度汉语里面下载汉字的发音,解释词条等制成卡片;3 I2 X4 m, Y: |' t$ m
    2. 从mdx词典文件里面将有需要的内容拿出来制成卡片;7 P% `5 H; k* V+ U$ |0 y3 p
    3. 用Selenium从一些不能简单用requests库扒的网站上扒数据制成卡;
    - ?8 B0 X  w" |4 p; O
    2 r; `+ z# q) x2 X: G首先请安装pycharm,这是一个非常好用的IDE,CE版本的是免费的,功能已经很全了。; C/ _, |9 Y7 N

    & l5 b' d0 D2 c/ `9 l- I然后新建一个项目,名字随便,这里就叫anki-scripting吧。0 N, w+ U# `- M% F
    参照Anki的手册里面的指导https://addon-docs.ankiweb.net/#/getting-started
    3 F; D. s/ Y! ]4 a+ Y) d在pycharm界面下方有一个console,点开就会出来Python的命令行解释器。2 r1 n1 u% i/ Z) K7 f$ I+ o
    1. import subprocess7 M# b: R3 g% S
    2. ( @8 @7 `6 ?1 f1 s+ u5 J
    3. subprocess.check_call(["pip3", "install", "--upgrade", "pip"])
        S6 k% m; j$ U) w9 n% B' O
    4. subprocess.check_call(["pip3", "install", "mypy", "aqt"])
    复制代码
    # K" }/ V$ x0 q' R2 Y
    等安装完成,我们的准备工作就完成了,如果失败请自行搜索解决。下面的内容敬请期待,准备上班去了。
    ( c1 x: a& ]- U" D2 [* q/ l  M2 c4 J
    ' I$ v1 a2 j4 Z. N6 [7 y, D! [
    , |9 t7 b7 ]5 V0 \  Z! `( }
    好了,在前面的准备工作的基础上,我们现在就可以来试着来用Python来操纵Anki了。  |+ }% v" u$ k4 b

    8 ?6 U! H3 u9 h: h1 c$ @$ CAnki的数据是保存在qlite3数据库里,在macOS上,路径是~/Library/Application Support/Anki2/username/collection.anki2,Windows的搜索一下。在用户名的文件夹下面,还有一个collection.media文件夹,这个里面保存的是媒体文件,MP3、图片之类的。4 T/ Q1 t$ O4 {4 A

    " X. |- K( ^# c1 Q( R. S" g) Z8 c* A下面我们可以点开PyCharm下面的Python Console。; W1 O# }# l1 j
    1. from anki.collection import Collection9 w! _* N' j5 ~! u
    2. col = Collection('path to your collection')
    复制代码

    - o: N# `. d6 D. dcollection.anki2文件的路径替换一下即可。这样我们就新建了一个collection的实例,注意,Anki软件要关掉。
    4 N0 \( }+ x+ n! R1 F/ k下面我们来看看能用这个干嘛。
      {9 b; v% S, m8 w" W1 v4 g
    1. # findNotes方法非常有用,查找的条件和你在Anki的浏览器里面是一样的,返回值是笔记的id号, 这里查找的条件是今天到期的笔记。/ N# M2 o0 M$ ~# \& i* _; T
    2. note_ids = col.findNotes('is:due')3 k( T; }9 Z3 ]0 H6 J
    3. # 获取笔记3 ^: [2 c, f- L! t4 |! j
    4. note = col.getNote(note_ids[0])8 Z. j. g0 L3 d  z, F6 Y
    5. # items方法可以获取字段名和字段内容的元组" D7 ?! }: u( V, I' \
    6. print(note.items())
      6 ^: T0 C  o5 Z; [/ ^3 H# H) \4 L
    7. # fields方法返回一个包含所有字段值的列表( |1 X; S3 ]3 _
    8. print(note.fields())
      ( I  U( `! J& W: k. V0 M) m3 m; o
    9. # model方法可以获取笔记的模板9 x* @; J- J7 U  E
    10. print(note.model())
      9 [) F& u; ]- U) }
    11. # 下面这条语句可以获取笔记的所有字段名8 f$ E1 {( S, ~) m) f$ f  P  m
    12. print(col.models.fieldsNames(note.model())
    复制代码

    7 H* P" C& T8 B* ~1 |: |0 y* K$ w9 y
      F5 c; M. w6 j/ ]" l, P+ R, p- a7 u' o& x/ m+ d
    好的,下面我们来获取今天到期的卡片的第一字段里面的内容并打印出来。) Y7 X: f5 v' `3 P6 `
    1. from anki.collection import Collection
      ' n% C, ~- s+ u& {1 f- O$ r
    2. col = Collection('path to your collection')9 l- C) L% x  @8 V
    3. note_ids = col.findNotes('is:due')
      7 g: ]$ i0 J0 E. I
    4. for nid in note_ids:
      9 L0 X+ p) P! x; g4 |
    5.     note = col.getNote(nid)
      1 e! v3 e5 P* M7 n
    6.     key = note.items()[0][1]
      ! `( l7 |( A+ i% k" E( |
    7.     print(key)
    复制代码

    / P7 n" ^$ y  i! U! n$ x- j" P( k
    - e: V1 R/ k6 v# |) }3 K你可能会想,我才不想列出这些呢,我是想修改卡片啊!!!!!别急,马上就到了。
    6 q* \% j$ @2 a, l  k
    * z9 |1 G/ z* B
    1. # 在 获取了note对象以后,只需要几个操作就可以完成对卡片的修改
      9 ]1 N( k' ]2 H" y2 \6 N5 s
    2. note['field_name'] = 'new value'
      - ]8 m( S( M8 }# i; ^/ n
    3. note.flush()! [5 _& i9 g# P7 Z. F0 d
    4. col.save()
    复制代码

    % k2 z8 D* L; p% q. `6 S) M6 ^- C8 ^' n/ T" c& z* J* _8 a/ F, C
    现在你可以获取一个note对象,然后对它进行一点小小的修改,试试看。
    3 A* V/ Z# p; v* A( y: F4 A; y7 J4 b1 ?/ _

    2 Q, R; @- G$ G% x0 @' A0 m8 r- M. I4 g7 A& f! o8 ?* F
    ) w) T+ f! i6 B- @; ^% n: a
    下面来讲讲如何新建卡片,在Anki里,你点击新建的时候,会默认选择当前的deck,以及当前deck的默认卡片类型,在Python里面,我们首先需要搞定这个。  m6 X1 z* U) B/ K$ x
      s4 U4 U, p% a) B$ v3 [
    1. # 下面有deck name 和 model name分别换成你要新建卡片的牌组名称和卡片类型名称        : h9 q2 O' S2 W, s  V
    2. # select deck+ k0 I) B/ e+ @3 H3 R, x9 E  o: [
    3.         col.decks.select(col.decks.byName('deck name')['id'])
      5 [1 ?3 I! v- @. f' U4 P" k  M3 q2 n
    4. 2 y4 }9 ?' \; o) f& d  H- r
    5.         # change current model
      ; _$ l: l' A, j
    6.         model = col.models.byName('model name')
      " o" q8 y6 }8 _7 f. A$ s' r
    7.         cdeck = col.decks.current()
      6 M! @% D, V0 `' U! i0 O9 Q
    8.         cdeck['mid'] = model['id']* o- H3 ?8 i2 R
    9.         col.decks.save(cdeck)
    复制代码
    , g, x2 G1 F% z' x& A9 A

    ' x# `6 B7 E5 ^
    8 F4 {+ `& r" q( r' T这样我们就完成了选择牌组和卡片类型,下面就到了新建卡片了。$ B/ K$ S- [1 t4 W/ O* k/ }. `
    1. note = col.newNote()  U% Y5 X- X2 a
    2. note.model()['did'] = col.decks.current()['id']! l/ q* B" b: A+ D
    3. note['field name'] = 'some value'
      / M2 H7 A3 _9 W
    4. col.addNote(note)9 P1 }( H; r! t. H( W3 N( ^
    5. col.save()
      - d- f$ o! f$ W1 [3 z: [
    6. col.close()
    复制代码
    & i! n- C$ o( f& Q& ^% y
    - h4 b4 u2 ]. L% s4 O
    新建了一条笔记后,可以分别给各个字段赋值,然后用addNote方法添加到collection中,记得要用save来保存,最后要关闭collection。4 w4 s" }2 E  ?8 t  ~4 h" G) o
    0 d/ E, b  M: J& l. B* z9 S
    现在动手试试自己添加一条笔记吧。

    本帖子中包含更多资源

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

    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
    4 B% v3 M7 s# [# K楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。

    , g2 x3 R" [& j+ x( l) r6 E
    * O! `; F6 r  h% I4 \% A1 Q我还没有录过视频,下次试试
  • 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-11 07:55 , Processed in 0.024487 second(s), 26 queries .

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

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