module Chez.Grater.Scraper.Site
( allScrapers, debugI, debugS
) where
import Chez.Grater.Internal.Prelude
import Chez.Grater.Scraper.Types
( IngredientScraper(..), ScrapeMeta(..), ScrapeName(..), ScrapeVersion(..), ScrapedIngredient(..)
, ScrapedStep(..), Scrapers(..), SiteName(..), StepScraper(..), inception
)
import Data.Function (on)
import Text.HTML.Scalpel ((//), (@:), (@=), Scraper, Selector)
import qualified Data.HashMap.Strict as HashMap
import qualified Data.Text as Text
import qualified Text.HTML.Scalpel as Scalpel
allScrapers :: Scrapers
allScrapers :: Scrapers
allScrapers = HashMap SiteName IngredientScraper
-> [IngredientScraper]
-> HashMap SiteName StepScraper
-> [StepScraper]
-> Scrapers
Scrapers HashMap SiteName IngredientScraper
ingredientScrapers [IngredientScraper]
allIngredientScrapers HashMap SiteName StepScraper
stepScrapers [StepScraper]
allStepScrapers
ingredientScrapers :: HashMap SiteName IngredientScraper
ingredientScrapers :: HashMap SiteName IngredientScraper
ingredientScrapers = [(SiteName, IngredientScraper)]
-> HashMap SiteName IngredientScraper
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
[ (SiteName
"allrecipes.com", IngredientScraper
allrecipesI)
, (SiteName
"cooking.nytimes.com", IngredientScraper
nytimesI)
, (SiteName
"food.com", IngredientScraper
geniusKitchen2I)
, (SiteName
"geniuskitchen.com", IngredientScraper
geniusKitchen1I)
, (SiteName
"tasteofhome.com", IngredientScraper
geniusKitchen1I)
, (SiteName
"rachlmansfield.com", IngredientScraper
tastyI2)
, (SiteName
"cookieandkate.com", IngredientScraper
tastyI1)
, (SiteName
"simpleveganblog.com", IngredientScraper
tastyI1)
, (SiteName
"eatyourselfskinny.com", IngredientScraper
tastyI1)
, (SiteName
"lexiscleankitchen.com", IngredientScraper
tastyI2)
, (SiteName
"sallysbakingaddiction.com", IngredientScraper
tastyI2)
, (SiteName
"gimmesomeoven.com", IngredientScraper
tastyI2)
, (SiteName
"pinchofyum.com", IngredientScraper
tastyI2)
, (SiteName
"alexandracooks.com", IngredientScraper
tastyI3)
, (SiteName
"naturallyella.com", IngredientScraper
tastyI3)
, (SiteName
"brownedbutterblondie.com", IngredientScraper
tastyI3)
, (SiteName
"foodnetwork.com", IngredientScraper
foodNetworkI)
, (SiteName
"cafedelites.com", IngredientScraper
wprmI)
, (SiteName
"budgetbytes.com", IngredientScraper
wprmI)
, (SiteName
"daringgourmet.com", IngredientScraper
wprmI)
, (SiteName
"recipetineats.com", IngredientScraper
wprmI)
, (SiteName
"cookingclassy.com", IngredientScraper
wprmI)
, (SiteName
"natashaskitchen.com", IngredientScraper
wprmI)
, (SiteName
"justonecookbook.com", IngredientScraper
wprmI)
, (SiteName
"loveandlemons.com", IngredientScraper
wprmI)
, (SiteName
"foodiecrush.com", IngredientScraper
wprmI)
, (SiteName
"therecipecritic.com", IngredientScraper
wprmI)
, (SiteName
"ambitiouskitchen.com", IngredientScraper
wprmI)
, (SiteName
"halfbakedharvest.com", IngredientScraper
wprmI)
, (SiteName
"ohsweetbasil.com", IngredientScraper
wprmI)
, (SiteName
"myfoodstory.com", IngredientScraper
wprmI)
, (SiteName
"easypeasyfoodie.com", IngredientScraper
wprmI)
, (SiteName
"veganricha.com", IngredientScraper
wprmI)
, (SiteName
"simplydeliciousfood.com", IngredientScraper
wprmI)
, (SiteName
"deliciouseveryday.com", IngredientScraper
wprmI)
, (SiteName
"iamafoodblog.com", IngredientScraper
wprmI)
, (SiteName
"thelastfoodblog.com", IngredientScraper
wprmI)
, (SiteName
"thefoodblog.net", IngredientScraper
wprmI)
, (SiteName
"onceuponafoodblog.com", IngredientScraper
wprmI)
, (SiteName
"anotherfoodblogger.com", IngredientScraper
wprmI)
, (SiteName
"minimalistbaker.com", IngredientScraper
wprmI)
, (SiteName
"davidlebovitz.com", IngredientScraper
wprmI)
, (SiteName
"skinnytaste.com", IngredientScraper
wprmI)
, (SiteName
"twopeasandtheirpod.com", IngredientScraper
wprmI)
, (SiteName
"sweetandsavorymeals.com", IngredientScraper
wprmI)
, (SiteName
"melskitchencafe.com", IngredientScraper
wprmI)
, (SiteName
"glutenfreecuppatea.co.uk", IngredientScraper
wprmI)
, (SiteName
"101cookbooks.com", IngredientScraper
cb101I)
, (SiteName
"bakerella.com", IngredientScraper
mvI)
, (SiteName
"localmilkblog.com", IngredientScraper
zlI)
, (SiteName
"smittenkitchen.com", IngredientScraper
jetpackI)
, (SiteName
"eatingwell.com", IngredientScraper
eatingWellI)
, (SiteName
"bhg.com", IngredientScraper
eatingWellI)
, (SiteName
"yummly.com", IngredientScraper
yummlyI)
, (SiteName
"simplyrecipes.com", IngredientScraper
simplyRecipesI)
, (SiteName
"seriouseats.com", IngredientScraper
simplyRecipesI)
, (SiteName
"bettycrocker.com", IngredientScraper
ingredientLi1)
, (SiteName
"pillsbury.com", IngredientScraper
ingredientLi1)
, (SiteName
"tasty.co", IngredientScraper
ingredientLi1)
, (SiteName
"lazycatkitchen.com", IngredientScraper
ingredientLi2)
, (SiteName
"deliciouslyella.com", IngredientScraper
ingredientLi3)
, (SiteName
"cookingandcooking.com", IngredientScraper
ingredientLi5)
, (SiteName
"damndelicious.net", IngredientScraper
ingredientLi6)
, (SiteName
"hemsleyandhemsley.com", IngredientScraper
ingredientLi6)
, (SiteName
"slenderkitchen.com", IngredientScraper
ingredientLi7)
, (SiteName
"everydayannie.com", IngredientScraper
ingredientLi8)
, (SiteName
"notwithoutsalt.com", IngredientScraper
ingredientLi9)
, (SiteName
"chefspencil.com", IngredientScraper
ingredientLi10)
, (SiteName
"shutterbean.com", IngredientScraper
ingredientLi11)
, (SiteName
"uitpaulineskeuken.nl", IngredientScraper
ingredientLi13)
, (SiteName
"leukerecepten.nl", IngredientScraper
ingredientLi14)
, (SiteName
"wsj.com", IngredientScraper
ingredientLi15)
, (SiteName
"delish.com", IngredientScraper
delishI)
, (SiteName
"thepioneerwoman.com", IngredientScraper
delishI)
, (SiteName
"spoonacular.com", IngredientScraper
spoonacularI)
, (SiteName
"food52.com", IngredientScraper
food52I)
, (SiteName
"thekitchn.com", IngredientScraper
thekitchnI)
, (SiteName
"eatwell101.com", IngredientScraper
eatwell101I)
, (SiteName
"bbcgoodfood.com", IngredientScraper
bbcGoodFoodI)
]
stepScrapers :: HashMap SiteName StepScraper
stepScrapers :: HashMap SiteName StepScraper
stepScrapers = [(SiteName, StepScraper)] -> HashMap SiteName StepScraper
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HashMap.fromList
[ (SiteName
"allrecipes.com", StepScraper
allrecipesS)
, (SiteName
"cooking.nytimes.com", StepScraper
nytimesS)
, (SiteName
"food.com", StepScraper
geniusKitchen2S)
, (SiteName
"geniuskitchen.com", StepScraper
geniusKitchen1S)
, (SiteName
"tasteofhome.com", StepScraper
geniusKitchen1S)
, (SiteName
"rachlmansfield.com", StepScraper
tastyS1)
, (SiteName
"cookieandkate.com", StepScraper
tastyS1)
, (SiteName
"simpleveganblog.com", StepScraper
tastyS1)
, (SiteName
"eatyourselfskinny.com", StepScraper
tastyS1)
, (SiteName
"lexiscleankitchen.com", StepScraper
tastyS1)
, (SiteName
"sallysbakingaddiction.com", StepScraper
tastyS2)
, (SiteName
"gimmesomeoven.com", StepScraper
tastyS2)
, (SiteName
"pinchofyum.com", StepScraper
tastyS2)
, (SiteName
"alexandracooks.com", StepScraper
tastyS2)
, (SiteName
"naturallyella.com", StepScraper
tastyS2)
, (SiteName
"brownedbutterblondie.com", StepScraper
tastyS3)
, (SiteName
"simple-veganista.com", StepScraper
tastyS4)
, (SiteName
"foodnetwork.com", StepScraper
foodNetworkS)
, (SiteName
"cafedelites.com", StepScraper
wprmS)
, (SiteName
"budgetbytes.com", StepScraper
wprmS)
, (SiteName
"daringgourmet.com", StepScraper
wprmS)
, (SiteName
"recipetineats.com", StepScraper
wprmS)
, (SiteName
"cookingclassy.com", StepScraper
wprmS)
, (SiteName
"natashaskitchen.com", StepScraper
wprmS)
, (SiteName
"justonecookbook.com", StepScraper
wprmS)
, (SiteName
"loveandlemons.com", StepScraper
wprmS)
, (SiteName
"foodiecrush.com", StepScraper
wprmS)
, (SiteName
"therecipecritic.com", StepScraper
wprmS)
, (SiteName
"ambitiouskitchen.com", StepScraper
wprmS)
, (SiteName
"halfbakedharvest.com", StepScraper
wprmS)
, (SiteName
"ohsweetbasil.com", StepScraper
wprmS)
, (SiteName
"myfoodstory.com", StepScraper
wprmS)
, (SiteName
"easypeasyfoodie.com", StepScraper
wprmS)
, (SiteName
"veganricha.com", StepScraper
wprmS)
, (SiteName
"simplydeliciousfood.com", StepScraper
wprmS)
, (SiteName
"deliciouseveryday.com", StepScraper
wprmS)
, (SiteName
"iamafoodblog.com", StepScraper
wprmS)
, (SiteName
"thelastfoodblog.com", StepScraper
wprmS)
, (SiteName
"thefoodblog.net", StepScraper
wprmS)
, (SiteName
"onceuponafoodblog.com", StepScraper
wprmS)
, (SiteName
"anotherfoodblogger.com", StepScraper
wprmS)
, (SiteName
"minimalistbaker.com", StepScraper
wprmS)
, (SiteName
"davidlebovitz.com", StepScraper
wprmS)
, (SiteName
"skinnytaste.com", StepScraper
wprmS)
, (SiteName
"twopeasandtheirpod.com", StepScraper
wprmS)
, (SiteName
"sweetandsavorymeals.com", StepScraper
wprmS)
, (SiteName
"melskitchencafe.com", StepScraper
wprmS)
, (SiteName
"glutenfreecuppatea.co.uk", StepScraper
wprmS)
, (SiteName
"101cookbooks.com", StepScraper
cb101S)
, (SiteName
"bakerella.com", StepScraper
mvS)
, (SiteName
"localmilkblog.com", StepScraper
zlS)
, (SiteName
"smittenkitchen.com", StepScraper
jetpackS)
, (SiteName
"eatingwell.com", StepScraper
eatingWellS)
, (SiteName
"bhg.com", StepScraper
eatingWellS)
, (SiteName
"yummly.com", StepScraper
yummlyS)
, (SiteName
"simplyrecipes.com", StepScraper
simplyRecipesS)
, (SiteName
"seriouseats.com", StepScraper
simplyRecipesS)
, (SiteName
"bettycrocker.com", StepScraper
stepLi1)
, (SiteName
"pillsbury.com", StepScraper
stepLi1)
, (SiteName
"tasty.co", StepScraper
stepLi2)
, (SiteName
"damndelicious.net", StepScraper
stepLi3)
, (SiteName
"lazycatkitchen.com", StepScraper
stepLi4)
, (SiteName
"deliciouslyella.com", StepScraper
stepLi5)
, (SiteName
"slenderkitchen.com", StepScraper
stepLi6)
, (SiteName
"everydayannie.com", StepScraper
stepLi7)
, (SiteName
"hemsleyandhemsley.com", StepScraper
stepLi8)
, (SiteName
"notwithoutsalt.com", StepScraper
stepLi9)
, (SiteName
"cookingandcooking.com", StepScraper
stepLi10)
, (SiteName
"uitpaulineskeuken.nl", StepScraper
stepLi11)
, (SiteName
"leukerecepten.nl", StepScraper
stepLi12)
, (SiteName
"wsj.com", StepScraper
stepLi13)
, (SiteName
"eatfigsnotpigs.com", StepScraper
stepLi14)
, (SiteName
"delish.com", StepScraper
delishS)
, (SiteName
"thepioneerwoman.com", StepScraper
delishS)
, (SiteName
"food52.com", StepScraper
food52S)
, (SiteName
"thekitchn.com", StepScraper
thekitchnS)
, (SiteName
"bbcgoodfood.com", StepScraper
bbcGoodFoodS)
]
allIngredientScrapers :: [IngredientScraper]
allIngredientScrapers :: [IngredientScraper]
allIngredientScrapers = ([IngredientScraper] -> IngredientScraper)
-> [[IngredientScraper]] -> [IngredientScraper]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [IngredientScraper] -> IngredientScraper
forall a. [a] -> a
head ([[IngredientScraper]] -> [IngredientScraper])
-> ([IngredientScraper] -> [[IngredientScraper]])
-> [IngredientScraper]
-> [IngredientScraper]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[IngredientScraper]] -> [[IngredientScraper]]
forall a. [a] -> [a]
reverse ([[IngredientScraper]] -> [[IngredientScraper]])
-> ([IngredientScraper] -> [[IngredientScraper]])
-> [IngredientScraper]
-> [[IngredientScraper]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([IngredientScraper] -> Int)
-> [[IngredientScraper]] -> [[IngredientScraper]]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn [IngredientScraper] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[IngredientScraper]] -> [[IngredientScraper]])
-> ([IngredientScraper] -> [[IngredientScraper]])
-> [IngredientScraper]
-> [[IngredientScraper]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IngredientScraper -> IngredientScraper -> Bool)
-> [IngredientScraper] -> [[IngredientScraper]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (ScrapeName -> ScrapeName -> Bool
forall a. Eq a => a -> a -> Bool
(==) (ScrapeName -> ScrapeName -> Bool)
-> (IngredientScraper -> ScrapeName)
-> IngredientScraper
-> IngredientScraper
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (ScrapeMeta ScrapedIngredient -> ScrapeName
forall a. ScrapeMeta a -> ScrapeName
scrapeMetaName (ScrapeMeta ScrapedIngredient -> ScrapeName)
-> (IngredientScraper -> ScrapeMeta ScrapedIngredient)
-> IngredientScraper
-> ScrapeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IngredientScraper -> ScrapeMeta ScrapedIngredient
ingredientScraperMeta)) ([IngredientScraper] -> [[IngredientScraper]])
-> ([IngredientScraper] -> [IngredientScraper])
-> [IngredientScraper]
-> [[IngredientScraper]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IngredientScraper -> ScrapeName)
-> [IngredientScraper] -> [IngredientScraper]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (ScrapeMeta ScrapedIngredient -> ScrapeName
forall a. ScrapeMeta a -> ScrapeName
scrapeMetaName (ScrapeMeta ScrapedIngredient -> ScrapeName)
-> (IngredientScraper -> ScrapeMeta ScrapedIngredient)
-> IngredientScraper
-> ScrapeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IngredientScraper -> ScrapeMeta ScrapedIngredient
ingredientScraperMeta) ([IngredientScraper] -> [IngredientScraper])
-> [IngredientScraper] -> [IngredientScraper]
forall a b. (a -> b) -> a -> b
$
HashMap SiteName IngredientScraper -> [IngredientScraper]
forall k v. HashMap k v -> [v]
HashMap.elems HashMap SiteName IngredientScraper
ingredientScrapers [IngredientScraper] -> [IngredientScraper] -> [IngredientScraper]
forall a. Semigroup a => a -> a -> a
<> [IngredientScraper
ingredientLi4, IngredientScraper
ingredientLi12]
allStepScrapers :: [StepScraper]
allStepScrapers :: [StepScraper]
allStepScrapers = ([StepScraper] -> StepScraper) -> [[StepScraper]] -> [StepScraper]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [StepScraper] -> StepScraper
forall a. [a] -> a
head ([[StepScraper]] -> [StepScraper])
-> (HashMap SiteName StepScraper -> [[StepScraper]])
-> HashMap SiteName StepScraper
-> [StepScraper]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[StepScraper]] -> [[StepScraper]]
forall a. [a] -> [a]
reverse ([[StepScraper]] -> [[StepScraper]])
-> (HashMap SiteName StepScraper -> [[StepScraper]])
-> HashMap SiteName StepScraper
-> [[StepScraper]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([StepScraper] -> Int) -> [[StepScraper]] -> [[StepScraper]]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn [StepScraper] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[StepScraper]] -> [[StepScraper]])
-> (HashMap SiteName StepScraper -> [[StepScraper]])
-> HashMap SiteName StepScraper
-> [[StepScraper]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StepScraper -> StepScraper -> Bool)
-> [StepScraper] -> [[StepScraper]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (ScrapeName -> ScrapeName -> Bool
forall a. Eq a => a -> a -> Bool
(==) (ScrapeName -> ScrapeName -> Bool)
-> (StepScraper -> ScrapeName)
-> StepScraper
-> StepScraper
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (ScrapeMeta ScrapedStep -> ScrapeName
forall a. ScrapeMeta a -> ScrapeName
scrapeMetaName (ScrapeMeta ScrapedStep -> ScrapeName)
-> (StepScraper -> ScrapeMeta ScrapedStep)
-> StepScraper
-> ScrapeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StepScraper -> ScrapeMeta ScrapedStep
stepScraperMeta)) ([StepScraper] -> [[StepScraper]])
-> (HashMap SiteName StepScraper -> [StepScraper])
-> HashMap SiteName StepScraper
-> [[StepScraper]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StepScraper -> ScrapeName) -> [StepScraper] -> [StepScraper]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (ScrapeMeta ScrapedStep -> ScrapeName
forall a. ScrapeMeta a -> ScrapeName
scrapeMetaName (ScrapeMeta ScrapedStep -> ScrapeName)
-> (StepScraper -> ScrapeMeta ScrapedStep)
-> StepScraper
-> ScrapeName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StepScraper -> ScrapeMeta ScrapedStep
stepScraperMeta) ([StepScraper] -> [StepScraper])
-> (HashMap SiteName StepScraper -> [StepScraper])
-> HashMap SiteName StepScraper
-> [StepScraper]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashMap SiteName StepScraper -> [StepScraper]
forall k v. HashMap k v -> [v]
HashMap.elems (HashMap SiteName StepScraper -> [StepScraper])
-> HashMap SiteName StepScraper -> [StepScraper]
forall a b. (a -> b) -> a -> b
$ HashMap SiteName StepScraper
stepScrapers
testScrape :: Selector -> Scraper Text Bool
testScrape :: Selector -> Scraper Text Bool
testScrape Selector
test = Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Bool
Text.null (Text -> Bool) -> ScraperT Text Identity Text -> Scraper Text Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Selector -> ScraperT Text Identity Text
forall str (m :: * -> *).
(StringLike str, Monad m) =>
Selector -> ScraperT str m str
Scalpel.html Selector
test
acceptAll :: Scraper Text Bool
acceptAll :: Scraper Text Bool
acceptAll = Bool -> Scraper Text Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
denyAll :: Scraper Text Bool
denyAll :: Scraper Text Bool
denyAll = Bool -> Scraper Text Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
setIngredientVersion :: Int -> IngredientScraper -> IngredientScraper
setIngredientVersion :: Int -> IngredientScraper -> IngredientScraper
setIngredientVersion Int
v IngredientScraper
scraper = IngredientScraper
scraper { ingredientScraperMeta :: ScrapeMeta ScrapedIngredient
ingredientScraperMeta = (IngredientScraper -> ScrapeMeta ScrapedIngredient
ingredientScraperMeta IngredientScraper
scraper) { scrapeMetaVersion :: ScrapeVersion
scrapeMetaVersion = Int -> ScrapeVersion
ScrapeVersion Int
v } }
setStepVersion :: Int -> StepScraper -> StepScraper
setStepVersion :: Int -> StepScraper -> StepScraper
setStepVersion Int
v StepScraper
scraper = StepScraper
scraper { stepScraperMeta :: ScrapeMeta ScrapedStep
stepScraperMeta = (StepScraper -> ScrapeMeta ScrapedStep
stepScraperMeta StepScraper
scraper) { scrapeMetaVersion :: ScrapeVersion
scrapeMetaVersion = Int -> ScrapeVersion
ScrapeVersion Int
v } }
simpleIngredientScraper :: Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper :: Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
sName Scraper Text Bool
test Selector
select = ScrapeMeta ScrapedIngredient
-> Scraper Text Bool
-> Scraper Text [ScrapedIngredient]
-> IngredientScraper
IngredientScraper (ScrapeName -> ScrapeVersion -> ScrapeMeta ScrapedIngredient
forall a. ScrapeName -> ScrapeVersion -> ScrapeMeta a
ScrapeMeta (Text -> ScrapeName
ScrapeName Text
sName) ScrapeVersion
inception) Scraper Text Bool
test Scraper Text [ScrapedIngredient]
scrape
where
scrape :: Scraper Text [ScrapedIngredient]
scrape = Selector
-> ScraperT Text Identity ScrapedIngredient
-> Scraper Text [ScrapedIngredient]
forall str (m :: * -> *) a.
(StringLike str, Monad m) =>
Selector -> ScraperT str m a -> ScraperT str m [a]
Scalpel.chroots Selector
select (
Text -> ScrapedIngredient
ScrapedIngredient
(Text -> ScrapedIngredient)
-> ScraperT Text Identity Text
-> ScraperT Text Identity ScrapedIngredient
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Selector -> ScraperT Text Identity Text
forall str (m :: * -> *).
(StringLike str, Monad m) =>
Selector -> ScraperT str m str
Scalpel.text Selector
Scalpel.anySelector
)
simpleStepScraper :: Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper :: Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
sName Scraper Text Bool
test Selector
select = ScrapeMeta ScrapedStep
-> Scraper Text Bool -> Scraper Text [ScrapedStep] -> StepScraper
StepScraper (ScrapeName -> ScrapeVersion -> ScrapeMeta ScrapedStep
forall a. ScrapeName -> ScrapeVersion -> ScrapeMeta a
ScrapeMeta (Text -> ScrapeName
ScrapeName Text
sName) ScrapeVersion
inception) Scraper Text Bool
test Scraper Text [ScrapedStep]
scrape
where
scrape :: Scraper Text [ScrapedStep]
scrape = Selector
-> ScraperT Text Identity ScrapedStep -> Scraper Text [ScrapedStep]
forall str (m :: * -> *) a.
(StringLike str, Monad m) =>
Selector -> ScraperT str m a -> ScraperT str m [a]
Scalpel.chroots Selector
select (
Text -> ScrapedStep
ScrapedStep
(Text -> ScrapedStep)
-> ScraperT Text Identity Text
-> ScraperT Text Identity ScrapedStep
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Selector -> ScraperT Text Identity Text
forall str (m :: * -> *).
(StringLike str, Monad m) =>
Selector -> ScraperT str m str
Scalpel.text Selector
Scalpel.anySelector
)
debugI :: IngredientScraper
debugI :: IngredientScraper
debugI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"debug" (Selector -> Scraper Text Bool
testScrape Selector
"div") Selector
"div"
debugS :: StepScraper
debugS :: StepScraper
debugS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"debug" (Selector -> Scraper Text Bool
testScrape Selector
"div") Selector
"div"
allrecipesI :: IngredientScraper
allrecipesI :: IngredientScraper
allrecipesI = Int -> IngredientScraper -> IngredientScraper
setIngredientVersion Int
2 (IngredientScraper -> IngredientScraper)
-> IngredientScraper -> IngredientScraper
forall a b. (a -> b) -> a -> b
$ Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"allrecipes"
(Selector -> Scraper Text Bool
testScrape (TagName
"meta" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"content" AttributeName -> String -> AttributePredicate
@= String
"Allrecipes"]))
(TagName
"span" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-item-name"])
allrecipesS :: StepScraper
allrecipesS :: StepScraper
allrecipesS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"allrecipes"
(Selector -> Scraper Text Bool
testScrape (TagName
"meta" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"content" AttributeName -> String -> AttributePredicate
@= String
"Allrecipes"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instructions-section"] Selector -> Selector -> Selector
// TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"section-body"])
nytimesI :: IngredientScraper
nytimesI :: IngredientScraper
nytimesI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"nytimes"
(Selector -> Scraper Text Bool
testScrape (TagName
"meta" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"content" AttributeName -> String -> AttributePredicate
@= String
"NYT Cooking"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-ingredients"] Selector -> Selector -> Selector
// Selector
"li")
nytimesS :: StepScraper
nytimesS :: StepScraper
nytimesS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"nytimes"
(Selector -> Scraper Text Bool
testScrape (TagName
"meta" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"content" AttributeName -> String -> AttributePredicate
@= String
"NYT Cooking"]))
(TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-steps"] Selector -> Selector -> Selector
// Selector
"li")
geniusKitchen1I :: IngredientScraper
geniusKitchen1I :: IngredientScraper
geniusKitchen1I = Int -> IngredientScraper -> IngredientScraper
setIngredientVersion Int
2 (IngredientScraper -> IngredientScraper)
-> IngredientScraper -> IngredientScraper
forall a b. (a -> b) -> a -> b
$ Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"geniusKitchen1"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-ingredients"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-ingredients"] Selector -> Selector -> Selector
// Selector
"li")
geniusKitchen2I :: IngredientScraper
geniusKitchen2I :: IngredientScraper
geniusKitchen2I = Int -> IngredientScraper -> IngredientScraper
setIngredientVersion Int
2 (IngredientScraper -> IngredientScraper)
-> IngredientScraper -> IngredientScraper
forall a b. (a -> b) -> a -> b
$ Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"geniusKitchen2"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients"] Selector -> Selector -> Selector
// Selector
"li")
geniusKitchen1S :: StepScraper
geniusKitchen1S :: StepScraper
geniusKitchen1S = Int -> StepScraper -> StepScraper
setStepVersion Int
2 (StepScraper -> StepScraper) -> StepScraper -> StepScraper
forall a b. (a -> b) -> a -> b
$ Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"geniusKitchen1"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-directions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-directions"] Selector -> Selector -> Selector
// Selector
"li")
geniusKitchen2S :: StepScraper
geniusKitchen2S :: StepScraper
geniusKitchen2S = Int -> StepScraper -> StepScraper
setStepVersion Int
2 (StepScraper -> StepScraper) -> StepScraper -> StepScraper
forall a b. (a -> b) -> a -> b
$ Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"geniusKitchen2"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"directions"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"directions"] Selector -> Selector -> Selector
// Selector
"li")
tastyI1 :: IngredientScraper
tastyI1 :: IngredientScraper
tastyI1 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"tasty1"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipe-ingredients"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipe-ingredients"] Selector -> Selector -> Selector
// Selector
"li")
tastyI2 :: IngredientScraper
tastyI2 :: IngredientScraper
tastyI2 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"tasty2"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-ingredients"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-ingredients"] Selector -> Selector -> Selector
// Selector
"li")
tastyI3 :: IngredientScraper
tastyI3 :: IngredientScraper
tastyI3 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"tasty3"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-ingredients"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-ingredients"] Selector -> Selector -> Selector
// Selector
"p")
tastyS1 :: StepScraper
tastyS1 :: StepScraper
tastyS1 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"tasty1"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipe-instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipe-instructions"] Selector -> Selector -> Selector
// Selector
"li")
tastyS2 :: StepScraper
tastyS2 :: StepScraper
tastyS2 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"tasty2"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-instructions"] Selector -> Selector -> Selector
// Selector
"li")
tastyS3 :: StepScraper
tastyS3 :: StepScraper
tastyS3 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"tasty3"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-instructions"] Selector -> Selector -> Selector
// TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipes-instructions-body"])
tastyS4 :: StepScraper
tastyS4 :: StepScraper
tastyS4 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"tasty4"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipe-instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"tasty-recipe-instructions"] Selector -> Selector -> Selector
// Selector
"p")
foodNetworkI :: IngredientScraper
foodNetworkI :: IngredientScraper
foodNetworkI = ScrapeMeta ScrapedIngredient
-> Scraper Text Bool
-> Scraper Text [ScrapedIngredient]
-> IngredientScraper
IngredientScraper (ScrapeName -> ScrapeVersion -> ScrapeMeta ScrapedIngredient
forall a. ScrapeName -> ScrapeVersion -> ScrapeMeta a
ScrapeMeta (Text -> ScrapeName
ScrapeName Text
"foodNetwork") ScrapeVersion
inception) Scraper Text Bool
denyAll (Scraper Text [ScrapedIngredient] -> IngredientScraper)
-> Scraper Text [ScrapedIngredient] -> IngredientScraper
forall a b. (a -> b) -> a -> b
$
(Text -> ScrapedIngredient) -> [Text] -> [ScrapedIngredient]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ScrapedIngredient
ScrapedIngredient ([Text] -> [ScrapedIngredient])
-> ([Text] -> [Text]) -> [Text] -> [ScrapedIngredient]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
(==) Text
"Deselect All") ([Text] -> [ScrapedIngredient])
-> ScraperT Text Identity [Text]
-> Scraper Text [ScrapedIngredient]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Selector
-> ScraperT Text Identity Text -> ScraperT Text Identity [Text]
forall str (m :: * -> *) a.
(StringLike str, Monad m) =>
Selector -> ScraperT str m a -> ScraperT str m [a]
Scalpel.chroots (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"o-Ingredients__m-Body"] Selector -> Selector -> Selector
// Selector
"span") (Selector -> ScraperT Text Identity Text
forall str (m :: * -> *).
(StringLike str, Monad m) =>
Selector -> ScraperT str m str
Scalpel.text Selector
Scalpel.anySelector)
foodNetworkS :: StepScraper
foodNetworkS :: StepScraper
foodNetworkS = ScrapeMeta ScrapedStep
-> Scraper Text Bool -> Scraper Text [ScrapedStep] -> StepScraper
StepScraper (ScrapeName -> ScrapeVersion -> ScrapeMeta ScrapedStep
forall a. ScrapeName -> ScrapeVersion -> ScrapeMeta a
ScrapeMeta (Text -> ScrapeName
ScrapeName Text
"foodNetwork") ScrapeVersion
inception) Scraper Text Bool
denyAll (Scraper Text [ScrapedStep] -> StepScraper)
-> Scraper Text [ScrapedStep] -> StepScraper
forall a b. (a -> b) -> a -> b
$ do
(Text -> ScrapedStep) -> [Text] -> [ScrapedStep]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> ScrapedStep
ScrapedStep ([Text] -> [ScrapedStep])
-> ScraperT Text Identity [Text] -> Scraper Text [ScrapedStep]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Selector
-> ScraperT Text Identity Text -> ScraperT Text Identity [Text]
forall str (m :: * -> *) a.
(StringLike str, Monad m) =>
Selector -> ScraperT str m a -> ScraperT str m [a]
Scalpel.chroots (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"o-Method__m-Body"] Selector -> Selector -> Selector
// Selector
"li") (Selector -> ScraperT Text Identity Text
forall str (m :: * -> *).
(StringLike str, Monad m) =>
Selector -> ScraperT str m str
Scalpel.text Selector
Scalpel.anySelector)
wprmI :: IngredientScraper
wprmI :: IngredientScraper
wprmI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"wprm"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"wprm-recipe"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"wprm-recipe-ingredient"])
wprmS :: StepScraper
wprmS :: StepScraper
wprmS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"wprm"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"wprm-recipe"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"wprm-recipe-instruction"])
cb101I :: IngredientScraper
cb101I :: IngredientScraper
cb101I = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"cb101"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cb101-recipe-main"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cb101-recipe-ingredient"])
cb101S :: StepScraper
cb101S :: StepScraper
cb101S = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"cb101"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cb101-recipe-main"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cb101-recipe-instruction"])
mvI :: IngredientScraper
mvI :: IngredientScraper
mvI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"mv"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"mv-create-ingredients"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"mv-create-ingredients"] Selector -> Selector -> Selector
// Selector
"li")
mvS :: StepScraper
mvS :: StepScraper
mvS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"mv"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"mv-create-instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"mv-create-instructions"] Selector -> Selector -> Selector
// Selector
"li")
zlI :: IngredientScraper
zlI :: IngredientScraper
zlI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"zl"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"zlrecipe-ingredients-list"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"zlrecipe-ingredients-list"] Selector -> Selector -> Selector
// Selector
"li")
zlS :: StepScraper
zlS :: StepScraper
zlS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"zl"
(Selector -> Scraper Text Bool
testScrape (TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"zlrecipe-instructions-list"]))
(TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"zlrecipe-instructions-list"] Selector -> Selector -> Selector
// Selector
"li")
jetpackI :: IngredientScraper
jetpackI :: IngredientScraper
jetpackI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"jetpack"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"jetpack-recipe"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"jetpack-recipe-ingredients"] Selector -> Selector -> Selector
// Selector
"li")
jetpackS :: StepScraper
jetpackS :: StepScraper
jetpackS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"jetpack"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"jetpack-recipe"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"jetpack-recipe-directions"])
eatingWellI :: IngredientScraper
eatingWellI :: IngredientScraper
eatingWellI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"eatingWell"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-section"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-section"] Selector -> Selector -> Selector
// Selector
"li")
eatingWellS :: StepScraper
eatingWellS :: StepScraper
eatingWellS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"eatingWell"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instructions-section"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instructions-section"] Selector -> Selector -> Selector
// Selector
"li" Selector -> Selector -> Selector
// Selector
"p")
yummlyI :: IngredientScraper
yummlyI :: IngredientScraper
yummlyI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"yummly"
Scraper Text Bool
denyAll
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"IngredientLine"])
yummlyS :: StepScraper
yummlyS :: StepScraper
yummlyS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"yummly"
Scraper Text Bool
denyAll
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"prep-step"])
simplyRecipesI :: IngredientScraper
simplyRecipesI :: IngredientScraper
simplyRecipesI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"simplyrecipes"
Scraper Text Bool
denyAll
(TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"section--ingredients_1-0"] Selector -> Selector -> Selector
// Selector
"li")
simplyRecipesS :: StepScraper
simplyRecipesS :: StepScraper
simplyRecipesS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"simplyrecipes"
Scraper Text Bool
denyAll
(TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"section--instructions_1-0"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi1 :: IngredientScraper
ingredientLi1 :: IngredientScraper
ingredientLi1 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi1"
(Selector -> Scraper Text Bool
testScrape (TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredient"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredient"])
ingredientLi2 :: IngredientScraper
ingredientLi2 :: IngredientScraper
ingredientLi2 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi2"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-section"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-section"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi3 :: IngredientScraper
ingredientLi3 :: IngredientScraper
ingredientLi3 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi3"
(Selector -> Scraper Text Bool
testScrape (TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"itemprop" AttributeName -> String -> AttributePredicate
@= String
"recipeIngredient"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"itemprop" AttributeName -> String -> AttributePredicate
@= String
"recipeIngredient"])
ingredientLi4 :: IngredientScraper
ingredientLi4 :: IngredientScraper
ingredientLi4 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi4"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi5 :: IngredientScraper
ingredientLi5 :: IngredientScraper
ingredientLi5 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi5"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"listIngredient"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"listIngredient"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi6 :: IngredientScraper
ingredientLi6 :: IngredientScraper
ingredientLi6 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi6"
(Selector -> Scraper Text Bool
testScrape (TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"itemprop" AttributeName -> String -> AttributePredicate
@= String
"ingredients"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"itemprop" AttributeName -> String -> AttributePredicate
@= String
"ingredients"])
ingredientLi7 :: IngredientScraper
ingredientLi7 :: IngredientScraper
ingredientLi7 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi7"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi8 :: IngredientScraper
ingredientLi8 :: IngredientScraper
ingredientLi8 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi8"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredient-text"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredient-text"] Selector -> Selector -> Selector
// Selector
"ul" Selector -> Selector -> Selector
// Selector
"li")
ingredientLi9 :: IngredientScraper
ingredientLi9 :: IngredientScraper
ingredientLi9 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi9"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cookbook-container-ingredients"]))
(TagName
"p" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cookbook-ingredient-item"])
ingredientLi10 :: IngredientScraper
ingredientLi10 :: IngredientScraper
ingredientLi10 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi10"
(Selector -> Scraper Text Bool
testScrape (TagName
"table" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-table"]))
(TagName
"table" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-table"] Selector -> Selector -> Selector
// Selector
"tr")
ingredientLi11 :: IngredientScraper
ingredientLi11 :: IngredientScraper
ingredientLi11 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi11"
(Selector -> Scraper Text Bool
testScrape (TagName
"blockquote" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-block"]))
(TagName
"blockquote" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-block"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi12 :: IngredientScraper
ingredientLi12 :: IngredientScraper
ingredientLi12 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi12"
(Selector -> Scraper Text Bool
testScrape (TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"structured-ingredients__list-item"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"structured-ingredients__list-item"])
ingredientLi13 :: IngredientScraper
ingredientLi13 :: IngredientScraper
ingredientLi13 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi13"
(Selector -> Scraper Text Bool
testScrape (TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-list"]))
(TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-list"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi14 :: IngredientScraper
ingredientLi14 :: IngredientScraper
ingredientLi14 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi14"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"page-content__ingredients-list"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"page-content__ingredients-list"] Selector -> Selector -> Selector
// Selector
"li")
ingredientLi15 :: IngredientScraper
ingredientLi15 :: IngredientScraper
ingredientLi15 = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"ingredientLi15"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-list"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredients-list"] Selector -> Selector -> Selector
// Selector
"li")
stepLi1 :: StepScraper
stepLi1 :: StepScraper
stepLi1 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi1"
(Selector -> Scraper Text Bool
testScrape (TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipeSteps"]))
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipeSteps"] Selector -> Selector -> Selector
// Selector
"li")
stepLi2 :: StepScraper
stepLi2 :: StepScraper
stepLi2 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi2"
(Selector -> Scraper Text Bool
testScrape (TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"prep-steps"]))
(TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"prep-steps"] Selector -> Selector -> Selector
// Selector
"li")
stepLi3 :: StepScraper
stepLi3 :: StepScraper
stepLi3 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi3"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instructions"] Selector -> Selector -> Selector
// Selector
"li")
stepLi4 :: StepScraper
stepLi4 :: StepScraper
stepLi4 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi4"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"method-section"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"method-section"] Selector -> Selector -> Selector
// Selector
"li")
stepLi5 :: StepScraper
stepLi5 :: StepScraper
stepLi5 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi5"
(Selector -> Scraper Text Bool
testScrape (TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe__section"]))
(TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe__section"] Selector -> Selector -> Selector
// Selector
"li")
stepLi6 :: StepScraper
stepLi6 :: StepScraper
stepLi6 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi6"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"step-instructions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"step-instructions"] Selector -> Selector -> Selector
// TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"step"])
stepLi7 :: StepScraper
stepLi7 :: StepScraper
stepLi7 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi7"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"directions"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [AttributeName
"id" AttributeName -> String -> AttributePredicate
@= String
"directions"] Selector -> Selector -> Selector
// Selector
"li")
stepLi8 :: StepScraper
stepLi8 :: StepScraper
stepLi8 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi8"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-main-copy"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe-main-copy"])
stepLi9 :: StepScraper
stepLi9 :: StepScraper
stepLi9 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi9"
(Selector -> Scraper Text Bool
testScrape (TagName
"p" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cookbook-instruction-item"]))
(TagName
"p" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"cookbook-instruction-item"])
stepLi10 :: StepScraper
stepLi10 :: StepScraper
stepLi10 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi10"
(Selector -> Scraper Text Bool
testScrape (TagName
"p" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipeText"]))
(TagName
"p" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipeText"])
stepLi11 :: StepScraper
stepLi11 :: StepScraper
stepLi11 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi11"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"preparation-list"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"preparation-list"] Selector -> Selector -> Selector
// Selector
"li")
stepLi12 :: StepScraper
stepLi12 :: StepScraper
stepLi12 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi12"
(Selector -> Scraper Text Bool
testScrape (TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"page-content__recipe"]))
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"page-content__recipe"] Selector -> Selector -> Selector
// TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"step"])
stepLi13 :: StepScraper
stepLi13 :: StepScraper
stepLi13 = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi13"
(Selector -> Scraper Text Bool
testScrape (TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"steps-list"]))
(TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"steps-list"] Selector -> Selector -> Selector
// Selector
"li")
stepLi14 :: StepScraper
stepLi14 :: StepScraper
stepLi14 = Int -> StepScraper -> StepScraper
setStepVersion Int
2 (StepScraper -> StepScraper) -> StepScraper -> StepScraper
forall a b. (a -> b) -> a -> b
$ Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"stepLi14"
(Selector -> Scraper Text Bool
testScrape (TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instruction"]))
(TagName
"li" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"instruction"])
delishI :: IngredientScraper
delishI :: IngredientScraper
delishI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"delish"
Scraper Text Bool
acceptAll
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"ingredient-item"])
delishS :: StepScraper
delishS :: StepScraper
delishS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"delish"
Scraper Text Bool
acceptAll
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"direction-lists"] Selector -> Selector -> Selector
// Selector
"li")
spoonacularI :: IngredientScraper
spoonacularI :: IngredientScraper
spoonacularI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"spoontacular"
Scraper Text Bool
denyAll
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"spoonacular-ingredient"])
food52I :: IngredientScraper
food52I :: IngredientScraper
food52I = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"food52"
Scraper Text Bool
denyAll
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe__list--ingredients"] Selector -> Selector -> Selector
// Selector
"li")
food52S :: StepScraper
food52S :: StepScraper
food52S = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"food52"
Scraper Text Bool
denyAll
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe__list--steps"] Selector -> Selector -> Selector
// Selector
"li")
thekitchnI :: IngredientScraper
thekitchnI :: IngredientScraper
thekitchnI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"thekitchn"
Scraper Text Bool
denyAll
(TagName
"ul" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"Recipe__ingredients"] Selector -> Selector -> Selector
// Selector
"li")
thekitchnS :: StepScraper
thekitchnS :: StepScraper
thekitchnS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"thekitchn"
Scraper Text Bool
denyAll
(TagName
"ol" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"Recipe__instructions"] Selector -> Selector -> Selector
// Selector
"li")
eatwell101I :: IngredientScraper
eatwell101I :: IngredientScraper
eatwell101I = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"eatwell101"
Scraper Text Bool
denyAll
(TagName
"div" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"pf-content"] Selector -> Selector -> Selector
// Selector
"li")
bbcGoodFoodI :: IngredientScraper
bbcGoodFoodI :: IngredientScraper
bbcGoodFoodI = Text -> Scraper Text Bool -> Selector -> IngredientScraper
simpleIngredientScraper Text
"bbcgoodfood"
Scraper Text Bool
denyAll
(TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe__ingredients"] Selector -> Selector -> Selector
// Selector
"li")
bbcGoodFoodS :: StepScraper
bbcGoodFoodS :: StepScraper
bbcGoodFoodS = Text -> Scraper Text Bool -> Selector -> StepScraper
simpleStepScraper Text
"bbcgoodfood"
Scraper Text Bool
denyAll
(TagName
"section" TagName -> [AttributePredicate] -> Selector
@: [String -> AttributePredicate
Scalpel.hasClass String
"recipe__method-steps"] Selector -> Selector -> Selector
// Selector
"li")