如何使用html5ever解析页面、修改DOM并序列化?

14

我希望能够解析一个网页,在指定的位置插入锚点,然后再次呈现修改后的DOM,以生成适用于Dash的文档集。这是否可能?

从html5ever中提供的示例中,我可以看到如何读取HTML文件并进行简单的HTML输出,但我不明白如何修改检索到的RcDom对象。

我想看到一小段代码,将锚点元素(<a name="foo"></a>)插入到RcDom中。

注意:这是关于Rust和html5ever的问题...我知道如何在其他语言或更简单的HTML解析器中完成。


使用更高级别的ScraperKuchiki解析HTML要比直接使用html5ever更容易。 - Wilfred Hughes
1个回答

17

这里有一些代码,它解析文档,为链接添加锚点并打印新文档:

extern crate html5ever;

use html5ever::{ParseOpts, parse_document};
use html5ever::tree_builder::TreeBuilderOpts;
use html5ever::rcdom::RcDom;
use html5ever::rcdom::NodeEnum::Element;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;

fn main() {
    let opts = ParseOpts {
        tree_builder: TreeBuilderOpts {
            drop_doctype: true,
            ..Default::default()
        },
        ..Default::default()
    };
    let data = "<!DOCTYPE html><html><body><a href=\"foo\"></a></body></html>".to_string();
    let dom = parse_document(RcDom::default(), opts)
        .from_utf8()
        .read_from(&mut data.as_bytes())
        .unwrap();

    let document = dom.document.borrow();
    let html = document.children[0].borrow();
    let body = html.children[1].borrow(); // Implicit head element at children[0].

    {
        let mut a = body.children[0].borrow_mut();
        if let Element(_, _, ref mut attributes) = a.node {
            attributes[0].value.push_tendril(&From::from("#anchor"));
        }
    }

    let mut bytes = vec![];
    serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
    let result = String::from_utf8(bytes).unwrap();
    println!("{}", result);
}

这将输出以下内容:

<html><head></head><body><a href="foo#anchor"></a></body></html>

正如您所看到的,我们可以通过 children 属性遍历子节点。

而且,我们可以更改 Element 的属性向量中存在的属性。


非常感谢,正是我所期望的。 - kesselborn
6
这个回答已经有1年了,但我今天刚尝试了这段代码,但它无法编译。 我使用的是Rust 1.20.0,并使用最新版本的html5ever。 错误是“unresolved import html5ever :: rcdom :: NodeEnum :: Element”,并且它说不再找到NodeEnum了。 它被弃用了吗? 我错过了什么吗? - ghlecl
看看这个例子 - 它使用了另一种看起来更新鲜的数据结构:https://github.com/servo/html5ever/blob/master/html5ever/examples/print-rcdom.rs - kirhgoff
1
更新后的示例链接(我想):https://github.com/servo/html5ever/blob/master/rcdom/examples/print-rcdom.rs - thomasa88

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接