aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoris2018-06-18 21:51:51 +0200
committerJoris2018-06-18 21:51:51 +0200
commit96bbdbbe9b22b3c3e96998cc18a3b68c9db66da9 (patch)
tree1a5e5e1b8d44c0a7dad614a1a0d5c7886a585d17 /src
parent3717598bb16a23097bbe1b4e676fd4e781eec640 (diff)
Fix ouest france ads encoding
Diffstat (limited to 'src')
-rw-r--r--src/executable/haskell/Service/AdListener.hs21
-rw-r--r--src/executable/haskell/Utils/HTTP.hs13
-rw-r--r--src/parser/haskell/Parser/Utils.hs1
-rw-r--r--src/test/haskell/Main.hs116
4 files changed, 83 insertions, 68 deletions
diff --git a/src/executable/haskell/Service/AdListener.hs b/src/executable/haskell/Service/AdListener.hs
index 8a66404..1025166 100644
--- a/src/executable/haskell/Service/AdListener.hs
+++ b/src/executable/haskell/Service/AdListener.hs
@@ -4,6 +4,7 @@ module Service.AdListener
import Control.Concurrent (threadDelay)
import Data.Either (rights)
+import Data.Text.Encoding as T
import qualified Data.Text.IO as T
import Prelude hiding (error)
@@ -47,14 +48,30 @@ listenToNewAdsWithViewedURLs conf viewedURLs = do
fetchAds :: Conf -> IO [Ad]
fetchAds conf = do
- leboncoinAds <- fmap (concat . map LeboncoinParser.parse . rights) . sequence . map HTTP.get . Conf.leboncoinUrls $ conf
- ouestFranceAds <- fmap (concat . map OuestFranceParser.parse . rights) . sequence . map HTTP.get . Conf.ouestFranceUrls $ conf
+ leboncoinAds <- getLeboncoinAds conf
+ ouestFranceAds <- getOuestFranceAds conf
let results = leboncoinAds ++ ouestFranceAds
if null results
then T.putStrLn "Parsed 0 results!"
else return ()
return results
+getLeboncoinAds :: Conf -> IO [Ad]
+getLeboncoinAds conf =
+ fmap (concat . map LeboncoinParser.parse . rights)
+ . sequence
+ . map (HTTP.get T.decodeLatin1)
+ . Conf.leboncoinUrls
+ $ conf
+
+getOuestFranceAds :: Conf -> IO [Ad]
+getOuestFranceAds conf =
+ fmap (concat . map OuestFranceParser.parse . rights)
+ . sequence
+ . map (HTTP.get T.decodeUtf8)
+ . Conf.ouestFranceUrls
+ $ conf
+
sendMail :: Conf -> [Ad] -> IO ()
sendMail conf ads =
let (title, plainBody) = Ad.renderAds ads
diff --git a/src/executable/haskell/Utils/HTTP.hs b/src/executable/haskell/Utils/HTTP.hs
index c901500..919e66d 100644
--- a/src/executable/haskell/Utils/HTTP.hs
+++ b/src/executable/haskell/Utils/HTTP.hs
@@ -3,18 +3,17 @@ module Utils.HTTP
) where
import Control.Exception (SomeException, try)
-
-import Data.ByteString.Lazy as BS
+import Data.ByteString (ByteString)
+import qualified Data.ByteString.Lazy as BS
import Data.Text (Text)
import qualified Data.Text as T
-import Data.Text.Encoding as T
import Network.HTTP.Conduit
import Model.URL
import Utils.Either (mapLeft)
-get :: URL -> IO (Either Text Text)
-get url = mapLeft (T.pack . show) <$> (try (unsafeGetPage url) :: IO (Either SomeException Text))
+get :: (ByteString -> Text) -> URL -> IO (Either Text Text)
+get decode url = mapLeft (T.pack . show) <$> (try (unsafeGetPage decode url) :: IO (Either SomeException Text))
-unsafeGetPage :: URL -> IO Text
-unsafeGetPage url = (T.decodeLatin1 . BS.toStrict) <$> simpleHttp (T.unpack url)
+unsafeGetPage :: (ByteString -> Text) -> URL -> IO Text
+unsafeGetPage decode url = (decode . BS.toStrict) <$> simpleHttp (T.unpack url)
diff --git a/src/parser/haskell/Parser/Utils.hs b/src/parser/haskell/Parser/Utils.hs
index 461808d..4768327 100644
--- a/src/parser/haskell/Parser/Utils.hs
+++ b/src/parser/haskell/Parser/Utils.hs
@@ -11,7 +11,6 @@ import Data.List (find, findIndex)
import Data.Maybe (catMaybes, listToMaybe)
import Data.Text (Text)
import qualified Data.Text as T
-
import Text.HTML.TagSoup
getTagsBefore :: Text -> [Tag Text] -> [Tag Text]
diff --git a/src/test/haskell/Main.hs b/src/test/haskell/Main.hs
index fae0a63..ccafba4 100644
--- a/src/test/haskell/Main.hs
+++ b/src/test/haskell/Main.hs
@@ -18,41 +18,41 @@ main = do
it "should parse ads from page" $ do
let ads =
- [ Ad {name = "Chambre style hotel", location = "Dinan", price = Just "265\160\8364", url = "https://www.leboncoin.fr/locations/1450271298.htm?ca=6_s"}
- , Ad {name = "Centre ville", location = "Brest", price = Just "420\160\8364", url = "https://www.leboncoin.fr/locations/1450271056.htm?ca=6_s"}
- , Ad {name = "T3, Morlaix proche centre ville et port plaisance", location = "Morlaix", price = Just "395\160\8364", url = "https://www.leboncoin.fr/locations/1407544500.htm?ca=6_s"}
- , Ad {name = "Appartement meuble", location = "Rennes", price = Just "565\160\8364", url = "https://www.leboncoin.fr/locations/1377975959.htm?ca=6_s"}
- , Ad {name = "A louer T3", location = "La Chapelle-Janson", price = Just "420\160\8364", url = "https://www.leboncoin.fr/locations/1450270098.htm?ca=6_s"}
- , Ad {name = "locations garage / garde meuble", location = "Landerneau", price = Just "50\160\8364", url = "https://www.leboncoin.fr/locations/1450174538.htm?ca=6_s"}
- , Ad {name = "Studio meubl\233", location = "Lanester", price = Just "290\160\8364", url = "https://www.leboncoin.fr/locations/1450268170.htm?ca=6_s"}
- , Ad {name = "Ergu\233-Gab\233ric - Maison - 3 chambres -", location = "Ergu\233-Gab\233ric", price = Just "655\160\8364", url = "https://www.leboncoin.fr/locations/1450267530.htm?ca=6_s"}
- , Ad {name = "Studio meubl\233 \224 2 mn de la gare", location = "Rennes", price = Just "475\160\8364", url = "https://www.leboncoin.fr/locations/1450267333.htm?ca=6_s"}
- , Ad {name = "Chambre \224 louer chez l,habitant", location = "Rennes", price = Just "450\160\8364", url = "https://www.leboncoin.fr/locations/1450266273.htm?ca=6_s"}
- , Ad {name = "Appartement 3 pi\232ces 63 m\178", location = "Brest", price = Just "600\160\8364", url = "https://www.leboncoin.fr/locations/1426927284.htm?ca=6_s"}
- , Ad {name = "recherche location", location = "Plaintel", price = Just "550\160\8364", url = "https://www.leboncoin.fr/locations/1450265866.htm?ca=6_s"}
- , Ad {name = "Studio r\233nov\233 - Centre Ville Lorient", location = "Lorient", price = Just "360\160\8364", url = "https://www.leboncoin.fr/locations/1450265154.htm?ca=6_s"}
- , Ad {name = "Centre historique, t2 meuble", location = "Vannes", price = Just "440\160\8364", url = "https://www.leboncoin.fr/locations/1450263864.htm?ca=6_s"}
- , Ad {name = "appartement t3 parking priv\233", location = "Pontrieux", price = Just "390\160\8364", url = "https://www.leboncoin.fr/locations/1450251207.htm?ca=6_s"}
- , Ad {name = "T1 Bis espace couchage ind\233pendant", location = "Brest", price = Just "360\160\8364", url = "https://www.leboncoin.fr/locations/1450263863.htm?ca=6_s"}
- , Ad {name = "Grand T2 boulevard Gambetta", location = "Brest", price = Just "400\160\8364", url = "https://www.leboncoin.fr/locations/1450263306.htm?ca=6_s"}
- , Ad {name = "chambre meubl\233e", location = "Bourg-des-Comptes", price = Just "300\160\8364", url = "https://www.leboncoin.fr/locations/1450246530.htm?ca=6_s"}
- , Ad {name = "Un studio de charme au centre de Landerneau", location = "Landerneau", price = Just "310\160\8364", url = "https://www.leboncoin.fr/locations/1433376198.htm?ca=6_s"}
- , Ad {name = "Appartement T2 plein centre.", location = "Plum\233liau", price = Just "385\160\8364", url = "https://www.leboncoin.fr/locations/1450262744.htm?ca=6_s"}
- , Ad {name = "Recherche l'appartement parfait", location = "Rennes", price = Just "360\160\8364", url = "https://www.leboncoin.fr/locations/1450260894.htm?ca=6_s"}
- , Ad {name = "Location appartement meuble", location = "Saint-Malo", price = Just "510\160\8364", url = "https://www.leboncoin.fr/locations/1421964890.htm?ca=6_s"}
- , Ad {name = "Maison neuve Lambezelec", location = "Plabennec", price = Just "900\160\8364", url = "https://www.leboncoin.fr/locations/1450259912.htm?ca=6_s"}
- , Ad {name = "Chambre kitchenette chez l'habitant", location = "Brest", price = Just "320\160\8364", url = "https://www.leboncoin.fr/locations/1450258838.htm?ca=6_s"}
- , Ad {name = "Studio 20m2 Rennes Ouest", location = "Rennes", price = Just "395\160\8364", url = "https://www.leboncoin.fr/locations/1450258223.htm?ca=6_s"}
- , Ad {name = "Maison Ploufragan", location = "Ploufragan", price = Just "680\160\8364", url = "https://www.leboncoin.fr/locations/1450257866.htm?ca=6_s"}
- , Ad {name = "Studio centre villes Rennes", location = "Rennes", price = Just "425\160\8364", url = "https://www.leboncoin.fr/locations/1450257277.htm?ca=6_s"}
- , Ad {name = "Grand T2 Saint-Brieuc proche Renan", location = "Saint-Brieuc", price = Just "375\160\8364", url = "https://www.leboncoin.fr/locations/1450257042.htm?ca=6_s"}
- , Ad {name = "Location maison T3", location = "Langueux", price = Just "569\160\8364", url = "https://www.leboncoin.fr/locations/1439054110.htm?ca=6_s"}
- , Ad {name = "Chambre", location = "Vannes", price = Just "150\160\8364", url = "https://www.leboncoin.fr/locations/1450255229.htm?ca=6_s"}
- , Ad {name = "Appartement meubl\233 2 ch centre Brest", location = "Brest", price = Just "750\160\8364", url = "https://www.leboncoin.fr/locations/1450255216.htm?ca=6_s"}
- , Ad {name = "Brest Base Navale/porte Caffa - possible meubl\233", location = "Brest", price = Just "390\160\8364", url = "https://www.leboncoin.fr/locations/1433862279.htm?ca=6_s"}
- , Ad {name = "Appartement Rennes", location = "Rennes", price = Just "390\160\8364", url = "https://www.leboncoin.fr/locations/1450254830.htm?ca=6_s"}
- , Ad {name = "Location Appartement Villejean", location = "Rennes", price = Just "400\160\8364", url = "https://www.leboncoin.fr/locations/1450253542.htm?ca=6_s"}
- , Ad {name = "Maison de bourg 3 chambres B\233d\233e", location = "B\233d\233e", price = Just "570\160\8364", url = "https://www.leboncoin.fr/locations/1450252631.htm?ca=6_s"}
+ [ Ad {name = "Chambre style hotel", location = "Dinan", price = Just "265 €", url = "https://www.leboncoin.fr/locations/1450271298.htm?ca=6_s"}
+ , Ad {name = "Centre ville", location = "Brest", price = Just "420 €", url = "https://www.leboncoin.fr/locations/1450271056.htm?ca=6_s"}
+ , Ad {name = "T3, Morlaix proche centre ville et port plaisance", location = "Morlaix", price = Just "395 €", url = "https://www.leboncoin.fr/locations/1407544500.htm?ca=6_s"}
+ , Ad {name = "Appartement meuble", location = "Rennes", price = Just "565 €", url = "https://www.leboncoin.fr/locations/1377975959.htm?ca=6_s"}
+ , Ad {name = "A louer T3", location = "La Chapelle-Janson", price = Just "420 €", url = "https://www.leboncoin.fr/locations/1450270098.htm?ca=6_s"}
+ , Ad {name = "locations garage / garde meuble", location = "Landerneau", price = Just "50 €", url = "https://www.leboncoin.fr/locations/1450174538.htm?ca=6_s"}
+ , Ad {name = "Studio meublé", location = "Lanester", price = Just "290 €", url = "https://www.leboncoin.fr/locations/1450268170.htm?ca=6_s"}
+ , Ad {name = "Ergué-Gabéric - Maison - 3 chambres -", location = "Ergué-Gabéric", price = Just "655 €", url = "https://www.leboncoin.fr/locations/1450267530.htm?ca=6_s"}
+ , Ad {name = "Studio meublé \224 2 mn de la gare", location = "Rennes", price = Just "475 €", url = "https://www.leboncoin.fr/locations/1450267333.htm?ca=6_s"}
+ , Ad {name = "Chambre \224 louer chez l,habitant", location = "Rennes", price = Just "450 €", url = "https://www.leboncoin.fr/locations/1450266273.htm?ca=6_s"}
+ , Ad {name = "Appartement 3 pièces 63 m\178", location = "Brest", price = Just "600 €", url = "https://www.leboncoin.fr/locations/1426927284.htm?ca=6_s"}
+ , Ad {name = "recherche location", location = "Plaintel", price = Just "550 €", url = "https://www.leboncoin.fr/locations/1450265866.htm?ca=6_s"}
+ , Ad {name = "Studio rénové - Centre Ville Lorient", location = "Lorient", price = Just "360 €", url = "https://www.leboncoin.fr/locations/1450265154.htm?ca=6_s"}
+ , Ad {name = "Centre historique, t2 meuble", location = "Vannes", price = Just "440 €", url = "https://www.leboncoin.fr/locations/1450263864.htm?ca=6_s"}
+ , Ad {name = "appartement t3 parking privé", location = "Pontrieux", price = Just "390 €", url = "https://www.leboncoin.fr/locations/1450251207.htm?ca=6_s"}
+ , Ad {name = "T1 Bis espace couchage indépendant", location = "Brest", price = Just "360 €", url = "https://www.leboncoin.fr/locations/1450263863.htm?ca=6_s"}
+ , Ad {name = "Grand T2 boulevard Gambetta", location = "Brest", price = Just "400 €", url = "https://www.leboncoin.fr/locations/1450263306.htm?ca=6_s"}
+ , Ad {name = "chambre meublée", location = "Bourg-des-Comptes", price = Just "300 €", url = "https://www.leboncoin.fr/locations/1450246530.htm?ca=6_s"}
+ , Ad {name = "Un studio de charme au centre de Landerneau", location = "Landerneau", price = Just "310 €", url = "https://www.leboncoin.fr/locations/1433376198.htm?ca=6_s"}
+ , Ad {name = "Appartement T2 plein centre.", location = "Pluméliau", price = Just "385 €", url = "https://www.leboncoin.fr/locations/1450262744.htm?ca=6_s"}
+ , Ad {name = "Recherche l'appartement parfait", location = "Rennes", price = Just "360 €", url = "https://www.leboncoin.fr/locations/1450260894.htm?ca=6_s"}
+ , Ad {name = "Location appartement meuble", location = "Saint-Malo", price = Just "510 €", url = "https://www.leboncoin.fr/locations/1421964890.htm?ca=6_s"}
+ , Ad {name = "Maison neuve Lambezelec", location = "Plabennec", price = Just "900 €", url = "https://www.leboncoin.fr/locations/1450259912.htm?ca=6_s"}
+ , Ad {name = "Chambre kitchenette chez l'habitant", location = "Brest", price = Just "320 €", url = "https://www.leboncoin.fr/locations/1450258838.htm?ca=6_s"}
+ , Ad {name = "Studio 20m2 Rennes Ouest", location = "Rennes", price = Just "395 €", url = "https://www.leboncoin.fr/locations/1450258223.htm?ca=6_s"}
+ , Ad {name = "Maison Ploufragan", location = "Ploufragan", price = Just "680 €", url = "https://www.leboncoin.fr/locations/1450257866.htm?ca=6_s"}
+ , Ad {name = "Studio centre villes Rennes", location = "Rennes", price = Just "425 €", url = "https://www.leboncoin.fr/locations/1450257277.htm?ca=6_s"}
+ , Ad {name = "Grand T2 Saint-Brieuc proche Renan", location = "Saint-Brieuc", price = Just "375 €", url = "https://www.leboncoin.fr/locations/1450257042.htm?ca=6_s"}
+ , Ad {name = "Location maison T3", location = "Langueux", price = Just "569 €", url = "https://www.leboncoin.fr/locations/1439054110.htm?ca=6_s"}
+ , Ad {name = "Chambre", location = "Vannes", price = Just "150 €", url = "https://www.leboncoin.fr/locations/1450255229.htm?ca=6_s"}
+ , Ad {name = "Appartement meublé 2 ch centre Brest", location = "Brest", price = Just "750 €", url = "https://www.leboncoin.fr/locations/1450255216.htm?ca=6_s"}
+ , Ad {name = "Brest Base Navale/porte Caffa - possible meublé", location = "Brest", price = Just "390 €", url = "https://www.leboncoin.fr/locations/1433862279.htm?ca=6_s"}
+ , Ad {name = "Appartement Rennes", location = "Rennes", price = Just "390 €", url = "https://www.leboncoin.fr/locations/1450254830.htm?ca=6_s"}
+ , Ad {name = "Location Appartement Villejean", location = "Rennes", price = Just "400 €", url = "https://www.leboncoin.fr/locations/1450253542.htm?ca=6_s"}
+ , Ad {name = "Maison de bourg 3 chambres Bédée", location = "Bédée", price = Just "570 €", url = "https://www.leboncoin.fr/locations/1450252631.htm?ca=6_s"}
]
LeboncoinParser.parse rawLeboncoinAds `shouldBe` ads
@@ -64,29 +64,29 @@ main = do
it "should parse ads from page" $ do
let ads =
- [ Ad {name = "Maison 3 chambres", location = "Rennes", price = Just "210\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13108048.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Sacr\233 Coeurs", price = Just "1 094\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13114249.htm"}
- , Ad {name = "Maison 1 pi\232ce", location = "Rennes Bourg L'ev\234que", price = Just "370\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13113524.htm"}
- , Ad {name = "Maison 2 chambres", location = "Rennes Sainte-Th\233r\232se", price = Just "869\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13111302.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Nord Saint-Martin", price = Just "1 650\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13109610.htm"}
- , Ad {name = "Maison 2 chambres", location = "Rennes Sainte-Th\233r\232se", price = Just "915\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13020322.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Brequigny", price = Just "1 011\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13107308.htm"}
- , Ad {name = "Maison 6 chambres", location = "Rennes Jeanne D'arc", price = Just "2 715\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13104531.htm"}
- , Ad {name = "Maison 3 chambres", location = "Rennes", price = Just "1 025\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13104556.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Patton", price = Just "1 270\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12742357.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Jeanne D'arc", price = Just "1 616\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12938970.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Sainte-Th\233r\232se", price = Just "1 910\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13050770.htm"}
- , Ad {name = "Maison 7 chambres", location = "Rennes Centre Ville", price = Just "3 000\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12888774.htm"}
- , Ad {name = "Maison 5 chambres", location = "Rennes Patton", price = Just "1 500\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12317304.htm"}
- , Ad {name = "Maison 6 chambres", location = "Rennes Sainte-Th\233r\232se", price = Just "1 850\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12874271.htm"}
- , Ad {name = "Maison 4 chambres", location = "Rennes Sud", price = Just "895\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11139843.htm"}
- , Ad {name = "Maison 3 chambres", location = "Rennes Cleunay", price = Just "760\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11538097.htm"}
- , Ad {name = "Maison 5 chambres", location = "Rennes Sud", price = Just "725\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11538087.htm"}
- , Ad {name = "Maison 2 pi\232ces", location = "Rennes Sacr\233 Coeurs", price = Just "420\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12892421.htm"}
- , Ad {name = "Maison 2 chambres", location = "Rennes Centre Ville", price = Just "700\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11918621.htm"}
- , Ad {name = "Maison 5 pi\232ces", location = "Rennes Arsenal - Redon", price = Just "760\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11139832.htm"}
- , Ad {name = "Maison 2 chambres", location = "Rennes Centre Ville", price = Just "900\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12247109.htm"}
- , Ad {name = "Maison 4 pi\232ces", location = "Rennes Nord Saint-Martin", price = Just "680\160\8364", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12973592.htm"}
+ [ Ad {name = "Maison 3 chambres", location = "Rennes", price = Just "210 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13108048.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Sacré Coeurs", price = Just "1 094 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13114249.htm"}
+ , Ad {name = "Maison 1 pièce", location = "Rennes Bourg L'evêque", price = Just "370 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13113524.htm"}
+ , Ad {name = "Maison 2 chambres", location = "Rennes Sainte-Thérèse", price = Just "869 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13111302.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Nord Saint-Martin", price = Just "1 650 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13109610.htm"}
+ , Ad {name = "Maison 2 chambres", location = "Rennes Sainte-Thérèse", price = Just "915 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13020322.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Brequigny", price = Just "1 011 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13107308.htm"}
+ , Ad {name = "Maison 6 chambres", location = "Rennes Jeanne D'arc", price = Just "2 715 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13104531.htm"}
+ , Ad {name = "Maison 3 chambres", location = "Rennes", price = Just "1 025 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13104556.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Patton", price = Just "1 270 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12742357.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Jeanne D'arc", price = Just "1 616 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12938970.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Sainte-Thérèse", price = Just "1 910 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/13050770.htm"}
+ , Ad {name = "Maison 7 chambres", location = "Rennes Centre Ville", price = Just "3 000 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12888774.htm"}
+ , Ad {name = "Maison 5 chambres", location = "Rennes Patton", price = Just "1 500 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12317304.htm"}
+ , Ad {name = "Maison 6 chambres", location = "Rennes Sainte-Thérèse", price = Just "1 850 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12874271.htm"}
+ , Ad {name = "Maison 4 chambres", location = "Rennes Sud", price = Just "895 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11139843.htm"}
+ , Ad {name = "Maison 3 chambres", location = "Rennes Cleunay", price = Just "760 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11538097.htm"}
+ , Ad {name = "Maison 5 chambres", location = "Rennes Sud", price = Just "725 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11538087.htm"}
+ , Ad {name = "Maison 2 pièces", location = "Rennes Sacré Coeurs", price = Just "420 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12892421.htm"}
+ , Ad {name = "Maison 2 chambres", location = "Rennes Centre Ville", price = Just "700 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11918621.htm"}
+ , Ad {name = "Maison 5 pièces", location = "Rennes Arsenal - Redon", price = Just "760 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/11139832.htm"}
+ , Ad {name = "Maison 2 chambres", location = "Rennes Centre Ville", price = Just "900 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12247109.htm"}
+ , Ad {name = "Maison 4 pièces", location = "Rennes Nord Saint-Martin", price = Just "680 €", url = "https://www.ouestfrance-immo.com//immobilier/location/maison/rennes-35-35238/12973592.htm"}
]
OuestFranceParser.parse rawOuestFranceAds `shouldBe` ads