71 lines
1.8 KiB
Rust
71 lines
1.8 KiB
Rust
pub trait SelectorBase {
|
|
fn from_html<S: AsRef<str>>(html: S) -> Self;
|
|
|
|
fn html(&self) -> String;
|
|
|
|
fn css<S: AsRef<str>>(&self, css_selector: S) -> Vec<Selector> {
|
|
let html = nipper::Document::from(self.html().as_str());
|
|
|
|
let mut output = vec![];
|
|
|
|
for item in html.select(css_selector.as_ref()).iter() {
|
|
output.push(Selector::from_html(item.html().to_string()))
|
|
}
|
|
output
|
|
}
|
|
|
|
fn css_once<S: AsRef<str>>(&self, css_selector: S) -> Option<Selector> {
|
|
self.css(css_selector.as_ref()).pop()
|
|
}
|
|
|
|
fn xpath<S: AsRef<str>>(&self, xpath: S) -> Vec<Selector> {
|
|
match cssifier::cssifier(xpath.as_ref()) {
|
|
Some(css_selector) => {
|
|
if css_selector.is_empty() {
|
|
Vec::default()
|
|
} else {
|
|
self.css(css_selector.as_str())
|
|
}
|
|
}
|
|
None => Vec::default(),
|
|
}
|
|
}
|
|
|
|
fn xpath_once<S: AsRef<str>>(&self, xpath: S) -> Option<Selector> {
|
|
self.xpath(xpath.as_ref()).pop()
|
|
}
|
|
|
|
fn content(&self) -> String {
|
|
let html = nipper::Document::from(self.html().as_str());
|
|
html.select("body > *")
|
|
.iter()
|
|
.map(|element| element.text().to_string())
|
|
.last()
|
|
.unwrap()
|
|
}
|
|
|
|
fn attr<'a>(&self, attribute: &'a str) -> Option<String> {
|
|
let html = nipper::Document::from(self.html().as_str());
|
|
html.select(" body > *")
|
|
.attr(attribute)
|
|
.map(|text| text.to_string())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Selector {
|
|
text: String,
|
|
}
|
|
|
|
impl SelectorBase for Selector {
|
|
fn from_html<S: AsRef<str>>(html: S) -> Self {
|
|
Selector {
|
|
text: html.as_ref().to_string(),
|
|
}
|
|
}
|
|
|
|
fn html(&self) -> String {
|
|
self.text.clone()
|
|
}
|
|
}
|