raspa/src/selector.rs

71 lines
1.8 KiB
Rust

pub trait SelectorBase {
fn from_html(html: String) -> 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(html: String) -> Self {
Selector {
text: html.to_string(),
}
}
fn html(&self) -> String {
self.text.clone()
}
}