Add search fnac

This commit is contained in:
Rémi BERTHO 2020-07-21 18:43:29 +02:00
parent 6233a754df
commit 13e04e4bdd
Signed by: dalan
GPG Key ID: EE3B917931C07B64
4 changed files with 28 additions and 8 deletions

View File

@ -3,7 +3,7 @@
* [x] Récupération prix darty avec [scraper](https://crates.io/crates/scraper) et [reqwest](https://crates.io/crates/reqwest) * [x] Récupération prix darty avec [scraper](https://crates.io/crates/scraper) et [reqwest](https://crates.io/crates/reqwest)
* [x] Ajout du support de la Fnac, … * [x] Ajout du support de la Fnac, …
* [x] Récupération URL ligne de commande avec [clap](https://crates.io/crates/clap) * [x] Récupération URL ligne de commande avec [clap](https://crates.io/crates/clap)
* [ ] Ajout de SearchParser pour rechercher un article sur tous les parseurs - retour si pas trouvé - recherche sur un seul parser * [ ] Ajout de SearchParser pour rechercher un article sur tous les parseurs - recherche sur un seul parser
* [x] Commande de liste des différents parseurs * [x] Commande de liste des différents parseurs
* [ ] Ajout des pays avec [celes](https://crates.io/crates/celes) : recherche uniquement sur les parser du pays et parseur multi pays (amazon par exemple) * [ ] Ajout des pays avec [celes](https://crates.io/crates/celes) : recherche uniquement sur les parser du pays et parseur multi pays (amazon par exemple)
* [ ] Lecture des URLs depuis un fichier avec [toml](https://crates.io/crates/toml) * [ ] Lecture des URLs depuis un fichier avec [toml](https://crates.io/crates/toml)

View File

@ -65,7 +65,7 @@ macro_rules! gen_list {
gen_list!( gen_list!(
[darty::Darty: get_price], [darty::Darty: get_price],
[fnac::Fnac: get_price], [fnac::Fnac: get_price, get_search],
[du_bruit_dans_la_cuisine::DuBruitDansLaCuisine: get_price], [du_bruit_dans_la_cuisine::DuBruitDansLaCuisine: get_price],
[ldlc::LDLC: get_price], [ldlc::LDLC: get_price],
[amazon::Amazon: get_price, get_search] [amazon::Amazon: get_price, get_search]
@ -75,5 +75,5 @@ gen_list!(
fn test_parser_list() { fn test_parser_list() {
let parser_list = List::new().unwrap(); let parser_list = List::new().unwrap();
assert_eq!(parser_list.get_price().len(), 5); assert_eq!(parser_list.get_price().len(), 5);
assert_eq!(parser_list.get_search().len(), 1); assert_eq!(parser_list.get_search().len(), 2);
} }

View File

@ -39,13 +39,13 @@ impl PriceParser for Amazon {
// Get price // Get price
let price_element = html.select(&self.price_selector).next().ok_or(anyhow!("No price element"))?; let price_element = html.select(&self.price_selector).next().ok_or(anyhow!("No price element"))?;
let mut price_text_it = price_element.text(); let mut price_text_it = price_element.text();
let price: f64 = price_text_it let price : f64 = price_text_it
.next() .next()
.unwrap_or("0.") .unwrap_or("0.")
.trim()
.trim_end_matches("") .trim_end_matches("")
.trim() .trim()
.replace(',', ".") .replace(',', ".").parse()?;
.parse()?;
// Get name // Get name
let name_element = html.select(&self.name_selector).next().ok_or(anyhow!("No name element"))?; let name_element = html.select(&self.name_selector).next().ok_or(anyhow!("No name element"))?;

View File

@ -1,4 +1,4 @@
use super::{Parser, PriceParser}; use super::{Parser, PriceParser, SearchParser};
use crate::PriceResult; use crate::PriceResult;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use scraper::{Html, Selector}; use scraper::{Html, Selector};
@ -10,6 +10,7 @@ pub struct Fnac {
price_selector: Selector, price_selector: Selector,
name_selector: Selector, name_selector: Selector,
product_selector: Selector, product_selector: Selector,
search_selector: Selector,
} }
impl Parser for Fnac { impl Parser for Fnac {
@ -18,6 +19,7 @@ impl Parser for Fnac {
price_selector: Selector::parse(r#".f-priceBox-price.checked"#).unwrap(), price_selector: Selector::parse(r#".f-priceBox-price.checked"#).unwrap(),
name_selector: Selector::parse(r#".f-productHeader-Title"#).unwrap(), name_selector: Selector::parse(r#".f-productHeader-Title"#).unwrap(),
product_selector: Selector::parse(r#".f-productHeader-subTitleLink"#).unwrap(), product_selector: Selector::parse(r#".f-productHeader-subTitleLink"#).unwrap(),
search_selector: Selector::parse(r#".Article-title"#).unwrap(),
}) })
} }
@ -28,7 +30,7 @@ impl Parser for Fnac {
impl PriceParser for Fnac { impl PriceParser for Fnac {
fn can_parse(&self, url: &Url) -> bool { fn can_parse(&self, url: &Url) -> bool {
url.host_str().unwrap_or("") == "www.fnac.com" url.host_str().unwrap_or("").ends_with("fnac.com")
} }
fn parse_price(&self, html: &Html) -> Result<PriceResult> { fn parse_price(&self, html: &Html) -> Result<PriceResult> {
@ -55,6 +57,24 @@ impl PriceParser for Fnac {
} }
} }
impl SearchParser for Fnac {
fn search_url(&self, name: &str) -> Url {
Url::parse(&format!(
"https://www.fnac.com/SearchResult/ResultList.aspx?Search={}",
name.replace(' ', "+")
))
.unwrap()
}
fn search(&self, html: &Html) -> Result<Option<Url>> {
if let Some(search_element) = html.select(&self.search_selector).next() {
let path_url = search_element.value().attr("href").ok_or(anyhow!("No link element"))?.trim_end_matches("#omnsearchpos=1");
Ok(Option::Some(Url::parse(path_url)?))
} else {
Ok(None)
}
}
}
#[test] #[test]
fn test_parser_fnac() { fn test_parser_fnac() {
let fnac_parser = Fnac::new().unwrap(); let fnac_parser = Fnac::new().unwrap();