前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >语雀文档批量导出为Markdown文件

语雀文档批量导出为Markdown文件

作者头像
KenTalk
发布2023-04-07 15:39:23
2.7K0
发布2023-04-07 15:39:23
举报
文章被收录于专栏:Ken的杂谈

一、前言

语雀的定位由之前的社区转向工具,也不提供批量导出Markdown的功能,有开发者提供了导出脚本可以通过语雀官方API帮我们把文档批量导出为Markdown,方便我们把文档导入notion等其他平台或者备份在本地,以备不时之需

环境依赖

工具

版本要求

本文环境

操作系统

macOS/Windows/Linux

Windows 11

Python

3.x

3.11

pip

from python 3.x

pip 22.3.1 from python 3.11

二、操作步骤

1、创建Token

登录语雀后在账户设置中可以创建Token,供访问API使用:https://www.yuque.com/settings/tokens/new 根据最小授权原则,这里只授予读取知识库以及文档的权限即可

image.png
image.png

2、安装Python

访问官网,下载自己操作系统对应的Python3 https://www.python.org/downloads/

image.png
image.png

查看版本

代码语言:javascript
复制
python -V

#输出内容
Python 3.11.0

#如果输出的是Python 2.x,可以使用Python3 -v查看
#后续依赖安装也要使用pip3命令

4、安装依赖

通过pip(Python内置包管理工具)安装代码所需依赖

代码语言:javascript
复制
pip install requests psutil

#输出内容
Collecting requests
  Downloading requests-2.28.1-py3-none-any.whl (62 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 62.8/62.8 kB 1.1 MB/s eta 0:00:00
Collecting psutil
  Downloading psutil-5.9.4-cp36-abi3-win_amd64.whl (252 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 252.5/252.5 kB 2.6 MB/s eta 0:00:00
###省略其他依赖安装内容###
Installing collected packages: urllib3, psutil, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2022.9.24 charset-normalizer-2.1.1 idna-3.4 psutil-5.9.4 requests-2.28.1 urllib3-1.26.13

5、代码及配置

创建导出目录,例如:d:\yuque,~/yuque 1、创建配置文件config.json

代码语言:javascript
复制
{
    "TOKEN": "your token",                                
    "USER_AGENT": "yuque_export",  
    "BASE_URL": "https://customspace.yuque.com/api/v2",
    "DATA_PATH": "yuque_data"                             
}

配置项

说明

TOKEN

替换为前面创建的Token

USER_AGENT

保持默认即可,无需调整

BASE_URL

语雀官方API地址,无误调整

DATA_PATH

文档导出目录,无需调整,会在导出目录中创建子目录

2、创建Python脚本yuque.py

代码语言:javascript
复制
import json
import sys
import os
import re
import requests
import psutil
from datetime import datetime

if getattr(sys, 'frozen', False):
    APPLICATION_PATH = os.path.dirname(sys.executable)
else:
    APPLICATION_PATH = os.path.dirname('.')
print(APPLICATION_PATH)
jsonConfig = json.load(open(os.path.join(APPLICATION_PATH, "config.json"), encoding='utf-8'))


class ExportYueQueDoc:
    def __init__(self):
        try:
            if getattr(sys, 'frozen', False):
                APPLICATION_PATH = os.path.dirname(sys.executable)
            else:
                APPLICATION_PATH = os.path.dirname('.')
            self.jsonConfig = json.load(open(os.path.join(APPLICATION_PATH, "config.json"), encoding='utf-8'))
            self.base_url = self.jsonConfig['BASE_URL']
            self.token = self.jsonConfig['TOKEN']
            self.headers = {
                "User-Agent": self.jsonConfig['USER_AGENT'],
                "X-Auth-Token": self.jsonConfig['TOKEN']
            }
            self.data_path = self.jsonConfig['DATA_PATH']
        except:
            raise ValueError("config.json 有误")

    def get_user_info(self):
        res_obj = requests.get(url=self.base_url + '/user', headers=self.headers)
        if res_obj.status_code != 200:
            raise ValueError("Token 信息错误")
        user_json = res_obj.json()
        self.login_id = user_json['data']['login']
        self.uid = user_json['data']['id']
        self.username = user_json['data']['name']
        print("=========== 用户信息初始化成功 ==========")

    def get_repos_data(self):
        repos_json = requests.get(self.base_url + '/users/' + self.login_id + '/repos', headers=self.headers).json()
        repos_list = []
        for item in repos_json['data']:
            rid = item['id']  # 知识库id
            name = item['name']  # 知识库名称
            repos_list.append({"rid": rid, "repos_name": name})
        return repos_list

    def get_article_data(self, repos_list):
        """获取文章数据"""
        article_list = []
        for repos in repos_list:
            article_datas = requests.get(self.base_url + '/repos/' + str(repos['rid']) + '/docs',
                                         headers=self.headers).json()
            for item in article_datas['data']:
                bid = repos['rid']
                title = item['title']  # 文章标题
                desc = item['description']
                slug = item['slug']
                article_list.append(
                    {"bid": bid, "title": title, "desc": desc, "slug": slug, "repos_name": repos["repos_name"]})

        for item in article_list:
            per_article_data = requests.get(self.base_url + '/repos/' + str(item['bid']) + '/docs/' + item['slug'],
                                            headers=self.headers).json()
            posts_text = re.sub(r'\\n', "\n", per_article_data['data']['body'])
            result = re.sub(r'<a name="(.*)"></a>', "", posts_text)
            # all_datas.append({"title": item['title'], "content": result})
            yield result, item["repos_name"], item['title']

    def save_article(self, result, repos_name, title):
        current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        dir_path = f"{self.data_path}/{repos_name}"
        dir_path = dir_path.replace(".","_")
        filepath = dir_path + f"/{title}.md"
        dir_ret = os.path.exists(dir_path)
        if not dir_ret:
            os.makedirs(dir_path)
            #exists_ret = os.path.exists(filepath)
        try:
            with open(filepath, 'a', encoding="utf-8") as fp:
                fp.writelines(result)
                print(f"[{current_time}]  {title} 导出完成")
        except Exception as e:
            print(f"[{current_time}]  {title} 导出失败")

    def main(self):
        self.get_user_info()
        repos_list = self.get_repos_data()
        gen_obj = self.get_article_data(repos_list)
        for item in gen_obj:
            self.save_article(item[0], item[1], item[2])


if __name__ == "__main__":
    yq = ExportYueQueDoc()
    yq.main()

6、执行导出

代码语言:javascript
复制
python yuque.py

#输出内容示例
=========== 用户信息初始化成功 ==========
[2022-12-06 22:56:55]  语雀批量导出Markdown-ken.io 写入完成
[2022-12-06 22:56:55]  浅谈软件设计模式与设计原则-ken.io 写入完成
[2022-12-06 22:56:55]  常用正则表达式收集-ken.io 写入完成
[2022-12-06 22:56:55]  XShell管理远程Linux服务器安装&配置教程-ken.io 写入完成
[2022-12-06 22:56:55]  Windows下Nginx安装与配置教程-ken.io 写入完成
[2022-12-06 22:56:55]  Ken.io 从ASP.NET Core 3.1迁移到5.0

导出成功后可以在config.json设置的目录中看到导出结果

image.png
image.png

三、备注

1、可能碰到的问题

Python版本问题

代码语言:javascript
复制
python yuque.py
#输出内容
  File "yuque.py", line 78
    dir_path = f"{self.data_path}/{repos_name}"
                                              ^
SyntaxError: invalid syntax

这种情况可能是因为系统安装了多个Python版本,而默认的Python版本是2.x 这时候我们可以用以下命令指定Python3

代码语言:javascript
复制
#安装依赖
pip3 install requests psutil

#执行导出
python3 yuque.py

2、本文参考

https://blog.csdn.net/weixin_44797182/article/details/128059847

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/12/06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
    • 环境依赖
    • 二、操作步骤
      • 1、创建Token
        • 2、安装Python
          • 4、安装依赖
            • 5、代码及配置
              • 6、执行导出
              • 三、备注
                • 1、可能碰到的问题
                  • 2、本文参考
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档