diff --git a/TODO.md b/TODO.md index d044984..0629b47 100644 --- a/TODO.md +++ b/TODO.md @@ -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] Ajout du support de la Fnac, … * [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 * [ ] 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) diff --git a/src/parser.rs b/src/parser.rs index 541499d..4bb8178 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -65,7 +65,7 @@ macro_rules! gen_list { gen_list!( [darty::Darty: get_price], - [fnac::Fnac: get_price], + [fnac::Fnac: get_price, get_search], [du_bruit_dans_la_cuisine::DuBruitDansLaCuisine: get_price], [ldlc::LDLC: get_price], [amazon::Amazon: get_price, get_search] @@ -75,5 +75,5 @@ gen_list!( fn test_parser_list() { let parser_list = List::new().unwrap(); assert_eq!(parser_list.get_price().len(), 5); - assert_eq!(parser_list.get_search().len(), 1); + assert_eq!(parser_list.get_search().len(), 2); } diff --git a/src/parser/amazon.rs b/src/parser/amazon.rs index 4714b1c..2dece7f 100644 --- a/src/parser/amazon.rs +++ b/src/parser/amazon.rs @@ -39,13 +39,13 @@ impl PriceParser for Amazon { // Get price let price_element = html.select(&self.price_selector).next().ok_or(anyhow!("No price element"))?; let mut price_text_it = price_element.text(); - let price: f64 = price_text_it + let price : f64 = price_text_it .next() .unwrap_or("0.") + .trim() .trim_end_matches("€") .trim() - .replace(',', ".") - .parse()?; + .replace(',', ".").parse()?; // Get name let name_element = html.select(&self.name_selector).next().ok_or(anyhow!("No name element"))?; diff --git a/src/parser/fnac.rs b/src/parser/fnac.rs index 8f84dcf..48af836 100644 --- a/src/parser/fnac.rs +++ b/src/parser/fnac.rs @@ -1,4 +1,4 @@ -use super::{Parser, PriceParser}; +use super::{Parser, PriceParser, SearchParser}; use crate::PriceResult; use anyhow::{anyhow, Result}; use scraper::{Html, Selector}; @@ -10,6 +10,7 @@ pub struct Fnac { price_selector: Selector, name_selector: Selector, product_selector: Selector, + search_selector: Selector, } impl Parser for Fnac { @@ -18,6 +19,7 @@ impl Parser for Fnac { price_selector: Selector::parse(r#".f-priceBox-price.checked"#).unwrap(), name_selector: Selector::parse(r#".f-productHeader-Title"#).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 { 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 { @@ -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> { + 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] fn test_parser_fnac() { let fnac_parser = Fnac::new().unwrap();