掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 2641|回复: 8

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

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

    [LV.6]常住居民II

    发表于 2021-2-19 07:28:36 | 显示全部楼层 |阅读模式
    本帖最后由 zhangchaont 于 2021-2-20 08:21 编辑 # |2 T3 c7 J* J3 N

    ' C, d% \8 z9 M' t我从2013年接触Anki,刚开始觉得很难上手,中间还放弃了一段时间,这次重新开始使用是从去年的2月份,我开始用Anki来学习日语,虽然中间也走了一些弯路,但是这个让我坚持下来了,以前去外面报学习班几次也没有学下来。现在Anki已经成了我的日常,而在这个过程中,我也学会了一些和原来的目标不一样的东西,我最开始是想学英语,后来想学日语。虽然这两个目标目前的效果还行,我英文的词汇量大概3万不到,可以比较自如的阅读英文书籍,听语音书的话80%以上吧,虽然写和说还欠缺,但是也不是不能克服的。日语学了一年,N2的水平自测没有问题,N1的语法马上学完了。除了这两个之外,因为要使用Anki,我还折腾会了一些意想不到的东西,比如:Python,html,CSS等等。会写Python的简单代码是我觉得最爽的事情,它让我觉得我身边的那些不会编程的人就像哈里波特里面的麻瓜。我女儿上一年级之前已经学会了3000个汉字,现在看书已经没什么障碍了。
    - Q' |  i# t$ q. B1 o+ A3 ~9 D) }  m3 c* b' F
    Anki已经有这么多好用的插件了,在制卡方面有FastWordQuery,为什么我们还需要自己写代码呢?因为我们各自的需求是非常个性化的,而一个插件不可能完全满足你的要求,要完全让自己满意,那就只好自己折腾了。 最开始的时候,我经常会写邮件给WordQuery(FastWordQuery的前身)的作者,向他请教一些问题,但是那时Python也不怎么会,所以还是不得要领。后来我偶然在网上找了了一篇帖子:$ V% m, e, x0 E* A4 ~; h
    https://www.juliensobczak.com/wr ... anki-scripting.html" |- ]% z& N  n6 v4 [: L* v
    这个对我非常有启发,不过好像要翻墙才能看到。我打印成PDF了,感兴趣的朋友可以下下来看看。
    6 y1 C, u+ {* |) V; j5 L- b& R后来我又在Anki的官方论坛里面提问,得到了Anki的作者Damien Elmes的指点,现在已经可以比较自如的用Python来制卡了。
    ! H4 Q1 h; ~" K" e
    0 S" u$ b; W, y9 \2 X) q! O9 |6 s好了,闲话不多说,在这个帖子里面,我将演示如何通过Python代码来:( M; u( K7 G- ~8 k
    1. 从百度汉语里面下载汉字的发音,解释词条等制成卡片;
    0 |; G6 T- a3 q, k" L& l2. 从mdx词典文件里面将有需要的内容拿出来制成卡片;
    ! W. i; j3 w" R( p- ^5 y: d. w3. 用Selenium从一些不能简单用requests库扒的网站上扒数据制成卡;$ h  S/ v" V$ j; `' h+ D

    ! R3 [# J2 a% N/ J' A4 Q6 y首先请安装pycharm,这是一个非常好用的IDE,CE版本的是免费的,功能已经很全了。0 g8 }7 v6 B1 p4 F) f5 [

    4 m5 ?5 B# ?0 s然后新建一个项目,名字随便,这里就叫anki-scripting吧。9 |$ @, T8 r7 W" d1 Y2 O$ s
    参照Anki的手册里面的指导https://addon-docs.ankiweb.net/#/getting-started- D  ]6 o( w% `3 a& y8 `9 X  J
    在pycharm界面下方有一个console,点开就会出来Python的命令行解释器。
    0 k6 Q) `1 @' j9 n; \" a, d3 R
    1. import subprocess+ B" A5 F0 A! C' A+ T) J

    2. 3 W) [- V- }) [2 P9 P# I' ]
    3. subprocess.check_call(["pip3", "install", "--upgrade", "pip"])
      & y" Y- ^3 `* \; k! V/ A4 ~9 u# t
    4. subprocess.check_call(["pip3", "install", "mypy", "aqt"])
    复制代码

    7 U- O+ }& H2 V2 w- @( I等安装完成,我们的准备工作就完成了,如果失败请自行搜索解决。下面的内容敬请期待,准备上班去了。
    $ u2 p4 h( v$ S- @$ M
    8 N, s' b5 d0 h0 N; ^$ O+ y- `
    + w1 k% o1 K& a/ J$ d. R" S) z) i; F; E/ u! O2 q/ S
    好了,在前面的准备工作的基础上,我们现在就可以来试着来用Python来操纵Anki了。
      ~7 s- X. ?8 h3 \; G; b$ G' }  r; _' R, v" b$ C" H$ h. K
    Anki的数据是保存在qlite3数据库里,在macOS上,路径是~/Library/Application Support/Anki2/username/collection.anki2,Windows的搜索一下。在用户名的文件夹下面,还有一个collection.media文件夹,这个里面保存的是媒体文件,MP3、图片之类的。0 ?/ T+ U& H" D- o
    % W) ?3 M+ ?9 E: n/ {, h4 |
    下面我们可以点开PyCharm下面的Python Console。$ ]4 ?, J8 t9 Z7 ~- H5 {4 W; _
    1. from anki.collection import Collection
      % Z) ?9 _- J% N4 u# {1 N
    2. col = Collection('path to your collection')
    复制代码

    . X3 z9 v; Y4 `% x; Fcollection.anki2文件的路径替换一下即可。这样我们就新建了一个collection的实例,注意,Anki软件要关掉。( D0 p- k4 `; F' C& N+ q4 B
    下面我们来看看能用这个干嘛。* u# C  D. {  Y& \- ]  h1 o! `. M6 R
    1. # findNotes方法非常有用,查找的条件和你在Anki的浏览器里面是一样的,返回值是笔记的id号, 这里查找的条件是今天到期的笔记。# a' t: F7 u  i0 I8 p- u7 `$ e
    2. note_ids = col.findNotes('is:due'). f( E1 \- |6 Y0 M) p
    3. # 获取笔记
      ) |1 q( ?, P: t
    4. note = col.getNote(note_ids[0])
      ( S2 X4 L, O8 c. N
    5. # items方法可以获取字段名和字段内容的元组
      ) _& Q7 v3 x/ T( [
    6. print(note.items())
      ; G; }% t8 {7 g; V+ F, }
    7. # fields方法返回一个包含所有字段值的列表$ I+ `3 I" {. Y5 A( n3 ^# M3 f
    8. print(note.fields())
      5 }' N7 x7 M# j$ u2 y( t
    9. # model方法可以获取笔记的模板
      + f; c& l7 h1 j8 n7 e% y
    10. print(note.model())
      * T! W9 k" C( Z1 w9 k; \! n$ s
    11. # 下面这条语句可以获取笔记的所有字段名8 N& v3 h8 W9 {! v! a4 W$ ?
    12. print(col.models.fieldsNames(note.model())
    复制代码
    ; p( w- _$ {% V- w9 g4 t

    3 p2 A1 ~. _! Q1 R! C
    " Z9 ^: A2 d1 p: I- a( x. Y好的,下面我们来获取今天到期的卡片的第一字段里面的内容并打印出来。' I2 I& C8 a. ?2 Q
    1. from anki.collection import Collection
      1 \9 r/ a# ^' I0 R
    2. col = Collection('path to your collection')% P* V; h4 @: U
    3. note_ids = col.findNotes('is:due')
      - V; A) v/ y2 K2 V' b
    4. for nid in note_ids:0 ^# U; S6 m: \% e1 w( Q1 n
    5.     note = col.getNote(nid)/ s( m0 m' R  D6 K: _' j
    6.     key = note.items()[0][1]; o8 j4 c5 Z- M8 O) l6 z
    7.     print(key)
    复制代码

    & u0 d& _* ?( w, N& Q* d; Z2 I. Y7 x) S! B
    你可能会想,我才不想列出这些呢,我是想修改卡片啊!!!!!别急,马上就到了。6 ]# Z* [$ c; T; b; z/ x1 h

    4 o. M* l( [% w0 i- s
    1. # 在 获取了note对象以后,只需要几个操作就可以完成对卡片的修改
      * k; W1 j7 q$ [* F" g6 @
    2. note['field_name'] = 'new value'! W2 {1 O9 [, P7 q3 D
    3. note.flush(): r: x5 c9 w+ S1 S6 ]
    4. col.save()
    复制代码

    ; f: P( @- S- ^* d( x! v1 c; K' y  {
    现在你可以获取一个note对象,然后对它进行一点小小的修改,试试看。
    4 Y1 V7 j9 X& W  m/ G3 V% a" t, x' E" _$ T+ N6 B6 u

    * F+ d: j& v3 O1 W: ]7 L3 Z3 Y* O" H. Z1 D) S3 r( V5 }7 p

    8 `" K- y5 q2 d5 U下面来讲讲如何新建卡片,在Anki里,你点击新建的时候,会默认选择当前的deck,以及当前deck的默认卡片类型,在Python里面,我们首先需要搞定这个。
    - P0 e9 Q- ?8 L* h2 {# X, L0 `2 b# h
    1. # 下面有deck name 和 model name分别换成你要新建卡片的牌组名称和卡片类型名称        : }2 [0 f7 V: a
    2. # select deck/ o" |( {7 P0 x8 n3 ]0 X
    3.         col.decks.select(col.decks.byName('deck name')['id'])
        d% P! J: k( P2 J

    4. 0 t+ a1 m" M& _3 k& `
    5.         # change current model: n1 S) h* w0 y% `3 Z) }9 S" Q
    6.         model = col.models.byName('model name')6 V1 s7 f7 U% m2 G8 {+ ~
    7.         cdeck = col.decks.current()
      " V, t7 U! S" J0 J  L$ C: b7 f
    8.         cdeck['mid'] = model['id']* O" p1 v: m) Q; k) E7 w
    9.         col.decks.save(cdeck)
    复制代码

    0 m' D& p" n) ^  J4 J
    ( _( @+ o: M: L' z
    ) R7 c" N9 R" V* v2 e这样我们就完成了选择牌组和卡片类型,下面就到了新建卡片了。
    8 Y! [$ x, v8 G
    1. note = col.newNote()
      # p6 `3 H( n* j: m( T2 c1 Y% a8 k
    2. note.model()['did'] = col.decks.current()['id']# U1 |* L) c, s, i2 d
    3. note['field name'] = 'some value'  X/ [5 i6 q$ W# |, u
    4. col.addNote(note)# P; l5 O- y  V$ W
    5. col.save()) z$ s6 M+ [/ X" o; U- @
    6. col.close()
    复制代码

    6 o% Z1 A6 A- C2 U
    / O" r8 A$ M/ q7 E, m9 j/ P. `新建了一条笔记后,可以分别给各个字段赋值,然后用addNote方法添加到collection中,记得要用save来保存,最后要关闭collection。  E9 A" Q& J% K8 y
    5 N' [1 U! @' _/ U/ B5 w+ o
    现在动手试试自己添加一条笔记吧。

    本帖子中包含更多资源

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

    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) T1 w; Y6 c* \. S7 o! a6 f
    楼主出个视频吧。我一般是用python操作csv文件,然后导入。相对简单点。

    7 j& Q) W# ~4 g9 V7 k: G
    ( A3 y% j( J5 a4 S9 ^7 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, 2024-5-16 09:47 , Processed in 0.061361 second(s), 10 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

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