likes
comments
collection
share

为了更舒服的阅读外文,我写了个小玩意儿起源 最近发现一个外文的周刊质量还挺不错的,值得每周花些时间阅读。网址为:Web

作者站长头像
站长
· 阅读数 20

起源

最近发现一个外文的周刊质量还挺不错的,值得每周花些时间阅读。网址为:Web Tools Weekly

不过原网站的排版狭窄,而且也有一些广告模块,加上又是英文的,虽然可以借助工具翻译,但毕竟阅读体验不是很好。所以想着能不能将其内容提取出来,整理成通用的markdown格式,然后翻译成中文,方便自己阅读。顺便还能存个档,以后查阅也方便。

说干就干,所以就有了这个项目。这个项目的功能包含以下几个方面:

  1. 提取文章内容,转换成markdown格式
  2. 翻译文章内容,并尽可能保留原文的格式
  3. 存档,分别存储原文和翻译后的文章

效果预览

首先一键运行脚本。成功后的输入如下:

为了更舒服的阅读外文,我写了个小玩意儿起源 最近发现一个外文的周刊质量还挺不错的,值得每周花些时间阅读。网址为:Web

这是转换后的原文内容:

为了更舒服的阅读外文,我写了个小玩意儿起源 最近发现一个外文的周刊质量还挺不错的,值得每周花些时间阅读。网址为:Web 再来看看翻译后的内容:

为了更舒服的阅读外文,我写了个小玩意儿起源 最近发现一个外文的周刊质量还挺不错的,值得每周花些时间阅读。网址为:Web

可以看到,翻译后的内容保留了原文的格式,包括标题、链接等。这样就可以保证翻译后的内容和原文的对应关系。整体的翻译效果也还不错,虽然有些地方翻译的不够准确,需要人工校对一下,但总体来说还是可以接受的。

而这整个过程,只需要一键运行脚本,等待大概2分钟,就可以完成。这样就大大提高了效率,也方便了阅读。

接下来,我们来看看这个项目的具体实现。

开发重点

文章内容提取

提取文章内容,转换成markdown格式,是整个项目的核心功能。这里使用了turndown库来解析网页内容,提取出文章内容。

turnDown.js是一个用于将HTML转换为Markdown的JavaScript库。它是一个轻量级的库,可以在浏览器和Node.js环境中使用。它支持HTML5,可以处理复杂的HTML和CSS。

它内置了一些默认的规则,可以将HTML转换为Markdown。但是,如果需要,还可以自定义规则,以满足特定的需求。

自定义规则

在这里,我们需要自定义一些规则,以满足我们的需求。比如,我们需要去除一些不必要的内容,比如广告模块,页脚等。我们还需要改写一些特定的内容,比如代码块。

这里给几个示例:

  1. 去除广告模块
turndownService.remove((node) => {
    return /xpost/.test(node.className);
  });
  1. 改写代码块
turndownService.addRule("codeArea", {
    filter: (node) => {
      return node.style.backgroundColor === "#272727";
    },
    replacement: function (content) {
      if (content.includes("```")) return content;
      return "```\n" + content + "\n```";
    },
  });

文章翻译

翻译文章内容,是整个项目的另一个核心功能。这里使用openai的API来实现翻译功能。

这里需要注意的一点是,文章整体的内容可能很多,如果一下子全部翻译,可能会导致超出API的token限制。所以这里需要将文章内容切分成多个部分,然后分别翻译,最后再合并。

内容切分与合并

首先,将文章按照换行符切分,然后指定需要合并的行数,将其合并成一个段落。这样就可以保证每个段落的内容不会超出API的token限制。

主要逻辑如下:

function mergeLines(fixedMarkdown) {
  const mergedMarkdown = []
  fixedMarkdown.split("\n").forEach((line, index) => {
    if (index % mergeLine === 0) {
      mergedMarkdown.push(line)
    } else {
      mergedMarkdown[mergedMarkdown.length - 1] += line+'\n'
    }
  })
  return mergedMarkdown
}

存档

存档是整个项目的最后一个功能。这里需要将原文和翻译后的文章内容分别存储到不同的文件中。以便以后查阅,也可以作为自己的创作发布。

大致代码如下:

async function main() {
  const fileName = url.split("/").pop();
  const { fixedMarkdown: mdContent, title } = await extract(url);
  console.log("提取成功!");
  fs.writeFileSync(
    path.join(__dirname, "archive", `${fileName}.md`),
    mdContent
  );
  console.log("原文写入成功!");
  const translatedContent = await translate(mdContent);
  console.log("翻译成功!");
  const extraContent = `\n\n文章翻译自:[${title}](${url}) \n\n`;
  const finalContent = translatedContent + extraContent;

  fs.writeFileSync(
    path.join(__dirname, "archive", "cn", `${fileName}.cn.md`),
    finalContent
  );
  console.log("译文写入成功!");
}

最后

项目里的自定义规则是针对Web Tools Weekly的,如果想要进行其他外文网站的内容提取和翻译,只需要修改自定义规则即可。其他逻辑几乎都是通用的。

上述代码只是整个项目的一个简单示例,实际项目中还有很多细节需要处理。如需查看完整代码,可以查看我的github仓库:web-tools-weekly-cn

转载自:https://juejin.cn/post/7362847673773244425
评论
请登录