#mediawiki #wikitext #mwbot

parsoid

围绕 Parsoid HTML 的包装器,提供方便的访问器以进行处理和操作

42 个版本

0.10.0-rc.22024 年 6 月 13 日
0.9.1 2024 年 1 月 23 日
0.9.0 2023 年 12 月 15 日
0.9.0-rc.12023 年 11 月 2 日
0.3.0-alpha.32020 年 11 月 12 日

#97 in 网络编程

Download history 1/week @ 2024-05-02 11/week @ 2024-05-16 35/week @ 2024-05-23 106/week @ 2024-05-30 263/week @ 2024-06-06 249/week @ 2024-06-13 135/week @ 2024-06-20 87/week @ 2024-06-27 123/week @ 2024-07-04 90/week @ 2024-07-11 96/week @ 2024-07-18 97/week @ 2024-07-25 93/week @ 2024-08-01 80/week @ 2024-08-08 66/week @ 2024-08-15

每月 350 次下载
用于 2 crates

GPL-3.0-or-later

180KB
3.5K SLoC

parsoid

crates.io docs.rs docs (main) pipeline status coverage report

parsoid crate 是围绕 Parsoid HTML 的包装器,提供方便的访问器以进行处理和提取。

mwparserfromhellparsoid-jsapi 启发,并在 Kuchiki (朽木) 的基础上构建。

快速入门

获取 HTML 并提取模板参数的值

use parsoid::prelude::*;
let client = ParsoidClient::new("https://en.wikipedia.org/w/rest.php", "parsoid-rs demo")?;
let code = client.get("Taylor_Swift").await?.into_mutable();
for template in code.filter_templates()? {
    if template.name() == "Template:Infobox person" {
        let birth_name = template.param("birth_name").unwrap();
        assert_eq!(birth_name, "Taylor Alison Swift");
    }
}

添加页面链接并将其转换为维基文本

use parsoid::prelude::*;
let client = ParsoidClient::new("https://en.wikipedia.org/w/rest.php", "parsoid-rs demo")?;
let code = client.get("Wikipedia:Sandbox").await?.into_mutable();
let link = WikiLink::new(
    "./Special:Random",
    &Wikicode::new_text("Visit a random page")
);
code.append(&link);
let wikitext = client.transform_to_wikitext(&code).await?;
assert!(wikitext.ends_with("[[Special:Random|Visit a random page]]"));

此 crate 不提供保存页面的功能,您需要使用类似 mwbot 的工具。

架构

从概念上讲,此 crate 在 HTML 处理库之上提供与维基相关的类型。有三个主要结构需要了解:WikicodeWikinodeTemplate

Wikicode 表示整个维基页面的容器,相当于一个 <html><body> 节点。它提供了一些便利函数,如 filter_links(),以便轻松操作和修改特定的 Wikinode。(为了方便,Wikicode 也是一个 Wikinode。)

use parsoid::prelude::*;
let client = ParsoidClient::new("https://en.wikipedia.org/w/rest.php", "parsoid-rs demo")?;
let code = client.get("Taylor Swift").await?.into_mutable();
for link in code.filter_links() {
    if link.target() == "You Belong with Me" {
        // ...do something
    }
}

仅针对常见类型提供筛选函数作为优化,但对于其他类型实现起来也很简单

use parsoid::prelude::*;
let client = ParsoidClient::new("https://en.wikipedia.org/w/rest.php", "parsoid-rs demo")?;
let code = client.get("Taylor Swift").await?.into_mutable();
let entities: Vec<HtmlEntity> = code
    .descendants()
    .filter_map(|node| node.as_html_entity())
    .collect();

Wikinode 是一个枚举,表示所有类型的 Wikinode,主要是为了使函数能够接受/返回各种类型的节点。

Wikinode为处理特定类型的MediaWiki结构提供了便捷函数。例如,WikiLink类型包装了一个节点,例如:<a rel="mw:WikiLink" href="...">...</a>。它提供了访问或修改href属性的功能。要访问链接文本,需要使用.children()并修改或追加这些节点。标准修改器,如.append().insert_after()WikinodeIterator特质的组成部分,该特质在预览中自动导入。

以下节点已经实现:

  • BehaviorSwitch__TOC__
  • Category[[Category:Foo]]
  • Comment<!-- ... -->
  • ExtLink[https://example.org Text]
  • Heading== Some text ==
  • HtmlEntity&nbsp;
  • IncludeOnly<includeonly>foo</includeonly>
  • InterwikiLink[[:en:Foo]]
  • LanguageLink[[en:Foo]]
  • Nowiki<nowiki>[[foo]]</nowiki>
  • Redirect#REDIRECT [[Foo]]
  • Section:包含一个Heading及其内容
  • WikiLink[[Foo|bar]]
  • Generic - 对于我们没有更具体类型的任何节点。

每个Wikinode实际上都是围绕Rc<Node>的一个包装,使其克隆变得便宜。

模板

与 Wikinodes 不同,模板与 HTML 节点之间没有 1:1 的映射,一个节点中可能包含多个模板。获取 Template 实例的主要方法是调用 Wikicode::filter_templates()

有关更多详情和示例,请参阅 Template 文档。

noinclude 和 onlyinclude

与模板类似,<noinclude><onlyinclude> 也没有与单个 HTML 节点进行 1:1 映射,因为它们可能跨越多个节点。获取 NoIncludeOnlyInclude 实例的主要方法是分别调用 filter_noinclude()filter_onlyinclude()

有关更多详情和示例,请参阅 模块级别 文档。

安全性

此库仅使用安全 Rust 实现,不应崩溃。然而,预期 HTML 达到一定程度的良好格式。例如,如果节点具有 rel="mw:WikiLink",则假定它是一个 <a> 元素。这不是为了完全防御任意 HTML,而应仅与来自 Parsoid 本身或通过此库或其他类似库变异的 HTML 一起使用(我们欢迎对此进行改进的贡献!)

此外,Wikicode 没有实现 Send,这意味着它不能在线程之间安全地共享。这是使用的基础 kuchikiki 库的限制。

提供 ImmutableWikicode 作为解决方案 - 它是 Send 且包含与 Wikicode 相同的所有信息,但它是不可变的。通过使用 into_immutable()into_mutable() 或使用标准 FromInto 特性来在两者之间切换非常简单。

测试

使用 build_corpus 示例下载英语维基百科的前 500 篇特色文章以创建测试语料库。

featured_articles 示例将遍历这些下载的示例以测试解析代码、清理往返等。

贡献

parsoidmwbot-rs 项目 的一部分。我们一直在寻找新的贡献者,如果您感兴趣,请 联系我们

许可证

此软件包在 GPL-3.0-or-later 许可证下发布。有关详情,请参阅 COPYING

依赖项

~5–18MB
~260K SLoC