导出有道词典单词本

2023-08-06
#python #有道词典 #爬虫

更新 2023-10-26

经由 @XYZ-99 提示才发现网页默认单词列表的只是【我的单词本】(猜测应该是默认的单词本,手机端可以设置),对于多单词本的情况下脚本无法一次性导出,所以对网页有道词典再次研究,发现了获取单词本的接口,以及对现有的接口的推测,对原有导出脚本再次升级了,现导出脚本支持导出所有的单词本的所有单词,项目地址 export-youdao

前言

有道词典功能太多了,奈何我只想要一个查单词、背单词然后没有广告的软件,所以最后决定投入欧陆词典的怀抱,迁移到过程中突然发现竟然 Macos 和 IOS 的有道词典没有导出单词本的功能,只好自己动手了。

导出脚本

import browser_cookie3
import requests
import time
import random
from typing import TypedDict, List

class Book(TypedDict):
    bookName: str
    bookId: str


cj = browser_cookie3.chrome()


def get_books() -> List[Book]:
    """
    获取所有的单词本列表
    """
    url = "https://dict.youdao.com/wordbook/webapi/v2/opts"
    resp = requests.get(url=url, cookies=cj)
    if resp.status_code != 200:
        print("请求有道单词本失败,请确保已经登录有道单词本: https://www.youdao.com/webwordbook/wordlist")
        return []
    response = resp.json()
    print("获取单词本列表成功,累计获取{}个单词本".format(len(response["data"]["book"])))
    return response["data"]["book"]


def get_words_by_book(limit, offset,sort, book:Book):
    url = "https://dict.youdao.com/wordbook/webapi/v2/word/list"
    resp = requests.get(url=url,params={
        "limit": limit,
        "offset": offset,
        "sort": sort,
        "lanTo": None,
        "lanFrom": None,
        "bookId": book["bookId"],
    }, cookies=cj)
    if resp.status_code != 200:
        print("请求有道单词本失败,请确保已经登录有道单词本: https://www.youdao.com/webwordbook/wordlist")
        return [], 0
    
    response = resp.json()
    total = response["data"]["total"]
    words = response["data"]["itemList"]
    return [word["word"] for word in words], total


def export_book_words(book:Book, limit=48, offset=0, sort="time"):
    words, total = get_words_by_book(limit, offset, sort, book)

    with open("words.txt", "a+") as f:
        f.write("\n".join(words))
        f.write("\n")
    
    offset += limit
    
    print("当前导出单词本【{}】 进度: {}/{}".format(book["bookName"], total if offset > total else offset, total))

    if offset  > total:
        print(f"导出单词本【{book['bookName']}】完成")
        return
    
    sleep_time = random.randint(1, 3)
    print("休息{}秒".format(sleep_time))
    time.sleep(sleep_time)

    return export_book_words(book, limit, offset, sort)    

def export_words_to_txt():
    books = get_books()
    if not books:
        return
    for book in books:
        print("单词本: {}".format(book["bookName"]))
        export_book_words(book)
        
    

if __name__ == "__main__":
    export_words_to_txt()

运行截图

image

最终导出一个 txt 文件,然后在欧路词典的网页端 https://my.eudic.net/studylist/import/ 进行导入

image