如何使用 html5ever 解析页面、修改 DOM 并序列化它?
How do I parse a page with html5ever, modify the DOM, and serialize it?
我想解析网页,在特定位置插入锚点并再次呈现修改后的 DOM,以便为 Dash 生成文档集。这可能吗?
从 html5ever 中包含的示例中,我可以看到如何读取 HTML 文件并执行可怜人的 HTML 输出,但我不明白如何修改 RcDom
我检索到的对象。
我希望看到将锚元素 (<a name="foo"></a>
) 插入 RcDom
的片段。
注意:这是一个关于 Rust 和 html5 的问题……我知道如何用其他语言或更简单的 HTML 解析器来做。
下面是一些解析文档、向 link 添加锚点并打印新文档的代码:
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
.
的属性向量中存在的属性
我想解析网页,在特定位置插入锚点并再次呈现修改后的 DOM,以便为 Dash 生成文档集。这可能吗?
从 html5ever 中包含的示例中,我可以看到如何读取 HTML 文件并执行可怜人的 HTML 输出,但我不明白如何修改 RcDom
我检索到的对象。
我希望看到将锚元素 (<a name="foo"></a>
) 插入 RcDom
的片段。
注意:这是一个关于 Rust 和 html5 的问题……我知道如何用其他语言或更简单的 HTML 解析器来做。
下面是一些解析文档、向 link 添加锚点并打印新文档的代码:
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
.