add the selector and the request base
parent
78e0c40cd6
commit
78bd9af763
|
@ -1,9 +1,14 @@
|
||||||
[package]
|
[package]
|
||||||
name = "raspa"
|
name = "raspa"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["kirbylife <gabriel13m@gmail.com>"]
|
authors = ["kirbylife <kirbylife@protonmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
reqwest = { version = "0.10", features = ["blocking", "json"] }
|
||||||
|
tokio = { version = "0.2", features = ["full"] }
|
||||||
|
url = "2.1"
|
||||||
|
http = "0.2"
|
||||||
|
nipper = "0.1.8"
|
31
src/lib.rs
31
src/lib.rs
|
@ -1,7 +1,34 @@
|
||||||
|
pub mod request;
|
||||||
|
pub mod response;
|
||||||
|
pub mod selector;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::request::{Request, RequestBase};
|
||||||
|
use crate::selector::{Selector, SelectorBase};
|
||||||
|
use http::StatusCode;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_works() {
|
fn plain_text_selector() {
|
||||||
assert_eq!(2 + 2, 4);
|
let html = "
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>hello world</h1>
|
||||||
|
<p id='text'>good bye</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
";
|
||||||
|
let sel = Selector::from_html(html);
|
||||||
|
println!("{:?}", sel.css("h1"));
|
||||||
|
assert_eq!(sel.css("h1")[0].html(), "<h1>hello world</h1>");
|
||||||
|
assert_eq!(sel.css("#text")[0].content(), "good bye");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple_request() {
|
||||||
|
let req: Request = RequestBase::new("https://httpbin.org/");
|
||||||
|
let resp = req.launch();
|
||||||
|
assert_eq!(resp.status_code, StatusCode::OK);
|
||||||
|
assert!(resp.css("h2")[0].html().contains("httpbin.org"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
use crate::response;
|
||||||
|
use http::status::StatusCode;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub trait RequestBase {
|
||||||
|
fn new(url: &'static str) -> Self;
|
||||||
|
fn launch(&self) -> response::Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Request {
|
||||||
|
pub url: url::Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RequestBase for Request {
|
||||||
|
fn new(url: &'static str) -> Request {
|
||||||
|
Request {
|
||||||
|
url: Url::parse(url).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn launch(&self) -> response::Response {
|
||||||
|
let resp = reqwest::blocking::get(self.url.as_str()).unwrap();
|
||||||
|
|
||||||
|
let text: String = resp.text().unwrap();
|
||||||
|
let status = StatusCode::OK;
|
||||||
|
|
||||||
|
let url = self.url.clone();
|
||||||
|
|
||||||
|
response::Response {
|
||||||
|
text: text,
|
||||||
|
status_code: status,
|
||||||
|
url: url,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
use crate::selector::SelectorBase;
|
||||||
|
use http::StatusCode;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Response {
|
||||||
|
pub text: String,
|
||||||
|
pub status_code: StatusCode,
|
||||||
|
pub url: Url,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SelectorBase for Response {
|
||||||
|
fn html(&self) -> &str {
|
||||||
|
self.text.as_str()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
pub trait SelectorBase {
|
||||||
|
fn html(&self) -> &str;
|
||||||
|
|
||||||
|
fn css(&self, css_selector: &'static str) -> Vec<Selector> {
|
||||||
|
let html = nipper::Document::from(self.html());
|
||||||
|
html.select(css_selector)
|
||||||
|
.iter()
|
||||||
|
.map(|element| Selector {
|
||||||
|
text: element.html().to_string(),
|
||||||
|
})
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn content(&self) -> String {
|
||||||
|
let html = nipper::Document::from(self.html());
|
||||||
|
html.select("*")
|
||||||
|
.iter()
|
||||||
|
.map(|element| element.text().to_string())
|
||||||
|
.last()
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Selector {
|
||||||
|
text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SelectorBase for Selector {
|
||||||
|
fn html(&self) -> &str {
|
||||||
|
self.text.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Selector {
|
||||||
|
pub fn from_html(html: &'static str) -> Self {
|
||||||
|
Selector {
|
||||||
|
text: html.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue