├── README.md └── duolingo-vocab-exporter.js /README.md: -------------------------------------------------------------------------------- 1 | Vocabulary export script for [Duolingo](http://duolingo.com/) 2 | === 3 | Written by Ruddick Lawrence 4 | --- 5 | 6 | Duolingo is an innovative (free!) way to learn new languages, but they don't provide an easy way to study just the vocabulary. Some people (like me) learn very quickly by studying flashcards, so I created this script to put the Duolingo vocabulary into CSV form (which can then easily be imported into a flashcard program/website). 7 | 8 | ### To run from the browser console: 9 | 1. Navigate to the Duolingo vocabulary page you want to convert (such as https://www.duolingo.com/words). Note that the script works on both the whole vocabulary and any subcategories. 10 | 1. Open up your browser's console (on Chrome it's Chrome menu > Tools > JavaScript Console) 11 | 1. Copy and paste the contents of duolingo-vocab-exporter.js into the console and press enter. 12 | 13 | Because of how the vocabulary pages work (they progressively load more words as you scroll to the bottom), you may have to wait a little as the script repeatedly scrolls down and loads all of the words. When it is finished, the page will be replaced by the CSV output, which you can copy into a new file and save with a .csv file extension. 14 | 15 | ### To turn into a bookmarklet: 16 | 1. Minify duolingo-vocab-exporter.js, such as by using http://jscompress.com (if you don't do this, the bookmarklet throws errors). 17 | 1. Create a new bookmark and title it whatever you want. 18 | 1. In the bookmark's URL field, type "javascript:" (without the quotes), and paste the minified code from step 1. 19 | 20 | This will allow you to click that bookmark while on any Duolingo vocab page to run the script. 21 | -------------------------------------------------------------------------------- /duolingo-vocab-exporter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Duolingo Vocab Exporter 3 | * Created by Ruddick Lawrence 4 | * =========================== 5 | * Javascript to create CSV vocab lists from 6 | * Duolingo vocab pages. Assumes jQuery is 7 | * loaded and a certain structure for the 8 | * vocab page (so it will break every 9 | * redesign they do). 10 | */ 11 | (function() { 12 | 13 | function scrapeVocab() { 14 | var vocab = []; 15 | // Get words and translations 16 | var wordRows = $('table.vocabulary > tbody').children('tr'); 17 | wordRows.each(function(index, row) { 18 | var $row = $(row); 19 | var wordInfo = null; 20 | // A new word 21 | if($row.hasClass('first-lemma-row')) { 22 | var canonicalWord = $row.find('td:first a').text(); 23 | wordInfo = { 24 | canonical: canonicalWord, 25 | otherForms: [], 26 | translations: [] 27 | }; 28 | vocab.push(wordInfo); 29 | } 30 | // Another form of previous word 31 | else { 32 | wordInfo = vocab[vocab.length-1]; 33 | } 34 | 35 | var lexeme = $row.children('td.lexeme'); 36 | var form = lexeme.find('.token').text(); 37 | if(form != wordInfo.canonical) { 38 | wordInfo.otherForms.push(form); 39 | } 40 | lexeme.find('tbody tr:not(.hidden) td').each(function(index, td) { 41 | wordInfo.translations.push($(td).text().trim()); 42 | }); 43 | }); 44 | 45 | // Format vocab list 46 | var csv = ""; 47 | $.each(vocab, function(index, item) { 48 | var words = item.canonical + (item.otherForms.length !== 0 ? ", " + item.otherForms.join(', ') : ""); 49 | var row = '"' + words + '","' + item.translations.join(', ') + '"\n'; 50 | csv += row; 51 | }); 52 | 53 | // Display list 54 | var pre = $('
');
55 | pre.text(csv);
56 | $('body').children().remove();
57 | $('body').append(pre);
58 | }
59 |
60 | function scrollDown() {
61 | // Indicates all words are loaded
62 | if($('#vocab-spinner').length === 0) {
63 | // Give a little time for last vocab to load
64 | // Should really just check if it's there, but whatever...
65 | setTimeout(scrapeVocab, 1000);
66 | }
67 | else {
68 | $(document).scrollTop($(document).height());
69 | setTimeout(scrollDown, 100);
70 | }
71 | }
72 |
73 | scrollDown();
74 | })();
--------------------------------------------------------------------------------