1+ //! Minimal HTML scraping adapter built on top of the `scraper` crate.
2+ //!
3+ //! This module provides a concrete `HtmlParser` implementation (`Scraper`)
4+ //! used by providers to extract content from HTML strings via CSS selectors.
5+ //! It converts `HtmlElement` inputs into a parsed document/fragment and
6+ //! exposes small helper methods to query elements, attributes and text.
7+ //!
8+ //! Notes and caveats:
9+ //! - Fragment parsing: most methods parse a small `HtmlElement` fragment and then select using `*` to reach the first real node via
10+ //! `nth(1)`. This aligns with how `scraper` represents fragment roots.
11+ //! - Selector parsing: `AsSelector` unwraps on parse errors; only valid CSS selectors should be passed.
12+ //! - Text extraction: `get_inner_text` returns the first text node trimmed. For complex nodes with multiple text parts, call it on
13+ //! the most specific element.
114use scraper:: { Element , ElementRef , Selector , html, node} ;
215
316use crate :: backend:: html_parser:: { HtmlElement , HtmlParser } ;
@@ -8,6 +21,8 @@ pub struct Scraper {
821}
922
1023impl Scraper {
24+ /// Creates a new `Scraper` by parsing the provided HTML string as a full
25+ /// document.
1126 #[ inline]
1227 pub fn new ( document : HtmlElement ) -> Self {
1328 let document = html:: Html :: parse_document ( & document) ;
@@ -17,6 +32,9 @@ impl Scraper {
1732
1833pub trait AsSelector {
1934 #![ allow( clippy:: wrong_self_convention) ]
35+ /// Converts a CSS selector string into a parsed `Selector`.
36+ ///
37+ /// Panics if the selector is invalid.
2038 fn as_selector ( self ) -> Selector ;
2139}
2240
@@ -28,6 +46,9 @@ impl AsSelector for &str {
2846}
2947
3048impl HtmlParser for Scraper {
49+ /// Returns the first text node inside the provided `HtmlElement` fragment,
50+ /// trimmed of surrounding whitespace. Returns an empty string if no text
51+ /// node is present.
3152 fn get_inner_text ( & self , document : & super :: HtmlElement ) -> String {
3253 let el = html:: Html :: parse_fragment ( document) ;
3354
@@ -41,6 +62,9 @@ impl HtmlParser for Scraper {
4162 }
4263
4364 #[ inline]
65+ /// Returns the first element matching `class` within the `from` fragment.
66+ /// The result is returned as a new `HtmlElement` containing the matched
67+ /// element's HTML.
4468 fn get_element_from ( & self , from : & HtmlElement , class : & str ) -> Option < HtmlElement > {
4569 html:: Html :: parse_fragment ( from)
4670 . select ( & class. as_selector ( ) )
@@ -49,17 +73,23 @@ impl HtmlParser for Scraper {
4973 }
5074
5175 #[ inline]
76+ /// Returns the inner HTML of the first child element within the provided
77+ /// fragment. If no child is found, returns an empty string.
5278 fn get_inner_html ( & self , document : & super :: HtmlElement ) -> String {
5379 let el = html:: Html :: parse_fragment ( document) ;
5480 el. select ( & "*" . as_selector ( ) ) . nth ( 1 ) . map ( |el| el. inner_html ( ) ) . unwrap_or_default ( )
5581 }
5682
5783 #[ inline]
84+ /// Selects the first element in the full document that matches `class` and
85+ /// returns it as an `HtmlElement`.
5886 fn get_element ( & self , class : & str ) -> Option < super :: HtmlElement > {
5987 self . document . select ( & class. as_selector ( ) ) . next ( ) . map ( |el| HtmlElement :: new ( el. html ( ) ) )
6088 }
6189
6290 #[ inline]
91+ /// Returns the value of attribute `attr_to_find` on the first child element
92+ /// within the provided fragment, if present.
6393 fn get_element_attr ( & self , element : & super :: HtmlElement , attr_to_find : & str ) -> Option < String > {
6494 let el = html:: Html :: parse_fragment ( element) ;
6595
@@ -71,20 +101,25 @@ impl HtmlParser for Scraper {
71101 }
72102
73103 #[ inline]
104+ /// Returns the children of the provided element fragment as individual
105+ /// `HtmlElement` nodes.
74106 fn get_element_children ( & self , element : & super :: HtmlElement ) -> Vec < super :: HtmlElement > {
75107 let doc = html:: Html :: parse_fragment ( element) ;
76108
77109 doc. select ( & "*" . as_selector ( ) ) . skip ( 2 ) . map ( |el| HtmlElement :: new ( el. html ( ) ) ) . collect ( )
78110 }
79111
80112 #[ inline]
113+ /// Returns all elements in the full document matching the CSS selector.
81114 fn get_matching_elements ( & self , selector : & str ) -> Vec < HtmlElement > {
82115 self . document
83116 . select ( & selector. as_selector ( ) )
84117 . map ( |el| HtmlElement :: new ( el. html ( ) ) )
85118 . collect ( )
86119 }
87120
121+ /// Returns all elements matching the CSS selector inside the provided
122+ /// fragment.
88123 fn get_matching_elements_from ( & self , from : & HtmlElement , class : & str ) -> Vec < HtmlElement > {
89124 html:: Html :: parse_fragment ( from)
90125 . select ( & class. as_selector ( ) )
0 commit comments