导出语雀所有文档为markdown文件(不需要超级会员tok

导出语雀所有文档为markdown文件(不需要超级会员tok

前言:2023-10-23日,语雀挂了一会,导致我没法写文档,这让我意识到文档全部放在云服务器上是不靠谱的,还需要进行本地备份,所以有了本篇文章内容。
重要提示:代码没有经过严谨测试,但我本人用起来没问题,我就不管了,不想浪费太多时间在这个上面,导出的文件会按每个知识库一个目录进行储存

<!-- apache http -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.10</version>
</dependency>

2、获取你的authToken和csrfToken

    首先进入你任意一个知识库,按下F12打开开发者工具,然后点击到网络,输入"yuque",然后清空日志,点击任意一篇文章,然后语雀会发送一个请求到语雀的服务器来获取你这篇文章的评论,这个请求中中就携带了你的authToken和csrfToken

在这里插入图片描述

然后在右边的标头中一直下滑,找到请求标头,即可看到authToken和csrfToken,分别复制到下面的代码中进行替换即可

在这里插入图片描述

`csharp
package org.jeecg.modules.system.test;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;

public class YuqueAPIClient {

static String authToken = "";

static String csrfToken = "";

public static void main(String[] args) {
    String baseURL = "https://www.yuque.com/api";
    //String personalBooksURL = "https://www.yuque.com/api/mine/raw_collab_books?offset=0&limit=30&query=";
    String personalBooksURL = baseURL + "/mine/personal_books";

    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        // Step 1: 获取所有知识库的Id
        HttpGet personalBooksRequest = new HttpGet(personalBooksURL);
        personalBooksRequest.setHeader("Cookie", authToken);
        personalBooksRequest.setHeader("X-Csrf-Token", csrfToken);

        HttpResponse personalBooksResponse = httpClient.execute(personalBooksRequest);
        HttpEntity personalBooksEntity = personalBooksResponse.getEntity();
        String personalBooksResponseString = EntityUtils.toString(personalBooksEntity);
        JSONObject personalBooksData = new JSONObject(personalBooksResponseString);
        JSONArray personalBooks = personalBooksData.getJSONArray("data");
        // 1.1、遍历知识库
        for (int i = 0; i < personalBooks.length(); i++) {
            JSONObject book = personalBooks.getJSONObject(i);
            String bookId = String.valueOf(book.get("id"));
            String bookName = (String) book.get("name");

            // Step 2: 获取知识库下的所有文章
            String bookURL = baseURL + "/docs/?book_id=" + bookId;
            HttpGet docRequest = new HttpGet(bookURL);
            docRequest.setHeader("Cookie", authToken);
            docRequest.setHeader("X-Csrf-Token", csrfToken);

            HttpResponse docResponse = httpClient.execute(docRequest);
            HttpEntity docEntity = docResponse.getEntity();
            String docResponseString = EntityUtils.toString(docEntity);
            JSONObject docData = new JSONObject(docResponseString);
            JSONArray docs = docData.getJSONArray("data");

            // Step 3: 遍历知识库下的有所文章
            for (int j = 0; j < docs.length(); j++) {
                JSONObject docEntry = docs.getJSONObject(j);
                String docId = String.valueOf(docEntry.get("id"));

                String exportURL = baseURL + "/docs/" + docId + "/export";
                HttpPost exportRequest = new HttpPost(exportURL);
                exportRequest.setHeader("Cookie", authToken);
                exportRequest.setHeader("X-Csrf-Token", csrfToken);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("type", "markdown");
                jsonObject.put("force", 0);

                // jsonObject.put("options", "{\"latexType\": 2,\"enableAnchor\": 0,\"enableBreak\": 0}");
                // latexType:1、导出 LaTeX 公式图片 2、导出 LaTeX 公式为 Markdown 语法
                // enableAnchor:导出保持语雀的锚点
                // enableBreak:导出保持语雀的换行
                jsonObject.put("options", "{\"latexType\":2}");
                StringEntity entity = new StringEntity(jsonObject.toString());
                entity.setContentType("application/json");
                exportRequest.setEntity(entity);

                HttpResponse exportResponse = httpClient.execute(exportRequest);
                HttpEntity exportEntity = exportResponse.getEntity();
                String exportResponseString = EntityUtils.toString(exportEntity);
                JSONObject exportData = new JSONObject(exportResponseString).getJSONObject("data");
                String downloadURL = (String) exportData.get("url");

                try {
                    // Step 3.1:保存文章到本地
                    saveFileFromURL(downloadURL, bookName);
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    } catch (IOException | JSONException e) {
        e.printStackTrace();
    }
}

public static void saveFileFromURL(String fileURL, String bookName) {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        HttpGet httpGet = new HttpGet(fileURL);
        httpGet.setHeader("Cookie", authToken);
        httpGet.setHeader("X-Csrf-Token", csrfToken);

        HttpResponse response = httpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        String fileName;
        if (response.getHeaders("Content-Disposition")[0].getElements()[0].getParameters().length == 2) {
            String file = response.getHeaders("Content-Disposition")[0].getElements()[0].getParameters()[1].getValue();
            fileName = URLDecoder.decode(file);
            fileName = fileName.substring(fileName.lastIndexOf("'"));
        }
        else
            fileName = response.getHeaders("Content-Disposition")[0].getElements()[0].getParameters()[0].getValue();
        if (entity!= null) {
            // 构建保存文件的目录路径
            File directory = new File("C:/Users/24730/Desktop/test" + bookName);
            // 检查目录是否存在,如果不存在则创建
            if (!directory.exists())  {
                if (!directory.mkdirs())  {
                    throw new IOException("Failed to create directory: " + directory.getAbsolutePath());
                }
            }
            try (InputStream inputStream = entity.getContent();
                 FileOutputStream outputStream = new FileOutputStream(new File(directory, fileName))) {
                byte[] buffer = new byte[1024];
                int n;
                while ((n = inputStream.read(buffer))!=  -1) {
                    outputStream.write(buffer,  0, n);
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值