#![deny(missing_docs)]
#[cfg(feature = "css_selector")]
pub mod css_selector;
pub mod error;
#[cfg(feature = "jsonpath")]
pub mod jsonpath;
#[cfg(feature = "xpath")]
pub mod xpath;
#[cfg(feature = "css_selector")]
use crate::css_selector::Html;
use crate::error::Result;
#[cfg(feature = "jsonpath")]
use crate::jsonpath::Json;
#[cfg(feature = "xpath")]
use crate::xpath::XHtml;
use async_trait::async_trait;
use error::ScraperError;
pub use reqwest::Response;
pub use reqwest_scraper_macros::{FromCssSelector, FromXPath};
#[cfg(feature = "xpath")]
pub trait FromXPath {
type XPathExtractResult;
fn from_xhtml(html: XHtml) -> Self::XPathExtractResult;
}
#[cfg(feature = "css_selector")]
pub trait FromCssSelector {
type CssSelectorExtractResult;
fn from_html(html: Html) -> Self::CssSelectorExtractResult;
}
#[async_trait]
pub trait ScraperResponse {
#[cfg(feature = "jsonpath")]
async fn jsonpath(self) -> Result<Json>;
#[cfg(feature = "css_selector")]
async fn css_selector(self) -> Result<Html>;
#[cfg(feature = "xpath")]
async fn xpath(self) -> Result<XHtml>;
}
#[async_trait]
impl ScraperResponse for Response {
#[cfg(feature = "jsonpath")]
async fn jsonpath(self) -> Result<Json> {
if self.status().is_success() {
let json_value = self.json().await?;
Ok(Json { value: json_value })
} else {
let status_code = self.status().as_u16();
let response = self.text().await?;
Err(ScraperError::HttpError(status_code, response))
}
}
#[cfg(feature = "css_selector")]
async fn css_selector(self) -> Result<Html> {
if self.status().is_success() {
let html_str = self.text().await?;
Ok(Html {
value: scraper::Html::parse_fragment(html_str.as_str()),
})
} else {
let status_code = self.status().as_u16();
let response = self.text().await?;
Err(ScraperError::HttpError(status_code, response))
}
}
#[cfg(feature = "xpath")]
async fn xpath(self) -> Result<XHtml> {
if self.status().is_success() {
let html_str = self.text().await?;
let parser = libxml::parser::Parser::default_html();
let doc = parser.parse_string(html_str)?;
Ok(XHtml { doc })
} else {
let status_code = self.status().as_u16();
let response = self.text().await?;
Err(ScraperError::HttpError(status_code, response))
}
}
}