Skyscraper - HTML scraping with XPath
Rust library to scrape HTML documents with XPath expressions.
This library is major-version 0 because there are still
todo!calls for many xpath features. If you encounter one that you feel should be prioritized, open an issue on GitHub.See the Supported XPath Features section for details.
HTML Parsing
Skyscraper has its own HTML parser implementation. The parser outputs a tree structure that can be traversed manually with parent/child relationships.
Example: Simple HTML Parsing
use ;
let html_text = r##"
<html>
<body>
<div>Hello world</div>
</body>
</html>"##;
let document = parse?;
Example: Traversing Parent/Child Relationships
// Parse the HTML text into a document
let text = r#"<parent><child/><child/></parent>"#;
let document = parse?;
// Get the children of the root node
let parent_node: DocumentNode = document.root_node;
let children: = parent_node.children.collect;
assert_eq!;
// Get the parent of both child nodes
let parent_of_child0: DocumentNode = children.parent.expect;
let parent_of_child1: DocumentNode = children.parent.expect;
assert_eq!;
assert_eq!;
XPath Expressions
Skyscraper is capable of parsing XPath strings and applying them to HTML documents.
Below is a basic xpath example. Please see the docs for more examples.
use html;
use ;
use Error;
Supported XPath Features
Below is a non-exhaustive list of all the features that are currently supported.
- Basic xpath steps:
/html/body/div,//div/table//span - Attribute selection:
//div/@class - Text selection:
//div/text() - Wildcard node selection:
//body/* - Predicates:
- Attributes:
//div[@class='hi'] - Indexing:
//div[1]
- Attributes:
- Functions:
fn:root()
- Forward axes:
- Child:
child::* - Descendant:
descendant::* - Attribute:
attribute::* - DescendentOrSelf:
descendant-or-self::* - (more coming soon)
- Child:
- Reverse axes:
- Parent:
parent::* - (more coming soon)
- Parent:
- Treat expressions:
/html treat as node()
This should cover most XPath use-cases. If your use case requires an unimplemented feature, please open an issue on GitHub.