diff --git a/README.rst b/README.rst index b124b33ee..ac16c5e2f 100644 --- a/README.rst +++ b/README.rst @@ -242,6 +242,7 @@ Scrapers available for: - `https://popsugar.com/ `_ - `https://practicalselfreliance.com/ `_ - `https://www.primaledgehealth.com/ `_ +- `https://www.projectgezond.nl/ `_ - `https://przepisy.pl/ `_ - `https://purelypope.com/ `_ - `https://purplecarrot.com/ `_ diff --git a/recipe_scrapers/__init__.py b/recipe_scrapers/__init__.py index 153da1dbd..a0659882e 100644 --- a/recipe_scrapers/__init__.py +++ b/recipe_scrapers/__init__.py @@ -157,6 +157,7 @@ from .popsugar import PopSugar from .practicalselfreliance import PracticalSelfReliance from .primaledgehealth import PrimalEdgeHealth +from .projectgezond import ProjectGezond from .przepisy import Przepisy from .purelypope import PurelyPope from .purplecarrot import PurpleCarrot @@ -391,6 +392,7 @@ PracticalSelfReliance.host(): PracticalSelfReliance, PracticalSelfReliance.host(domain="creativecanning.com"): PracticalSelfReliance, PrimalEdgeHealth.host(): PrimalEdgeHealth, + ProjectGezond.host(): ProjectGezond, Przepisy.host(): Przepisy, PurelyPope.host(): PurelyPope, PurpleCarrot.host(): PurpleCarrot, diff --git a/recipe_scrapers/projectgezond.py b/recipe_scrapers/projectgezond.py new file mode 100644 index 000000000..992b561c9 --- /dev/null +++ b/recipe_scrapers/projectgezond.py @@ -0,0 +1,96 @@ +# mypy: allow-untyped-defs +import re + +from ._abstract import AbstractScraper + + +class ProjectGezond(AbstractScraper): + @classmethod + def host(cls): + return "projectgezond.nl" + + def author(self): + return "Project Gezond" + + def title(self): + return self.soup.find("h1", {"class": "entry-title"}).text + + def category(self): + return ", ".join( + [ + element.text + for element in self.soup.find( + "span", {"class": "meta-category"} + ).find_all( + "a", {"class": lambda x: x is not None and x.startswith("category")} + ) + ] + ) + + def total_time(self): + time_element = self.soup.find("em", string="Bereidingstijd:").parent + return "".join( + [ + element.text + for element in time_element.children + if element.text != "Bereidingstijd:" + ] + ).strip() + + def yields(self): + # Match everything in the h2 with 'Dit heb je nodig' + # The text inside the parentheses contains the yield for the ingredients that are listed + return re.search( + r"Dit heb je nodig \(([^)]+)", + self.soup.find( + "h2", string=lambda x: x.startswith("Dit heb je nodig") + ).text, + ).group(1) + + def image(self): + return self.schema.image() + + def ingredients(self): + ingredients_table = self.soup.find( + "h2", string=lambda x: x.startswith("Dit heb je nodig") + ).next_sibling.next_sibling + ingredients = [ + ingredient.text + for ingredient in ingredients_table + if ingredient.text.strip() + ] + return ingredients + + def instructions(self): + instructions_table = self.soup.find( + "h2", string=lambda x: x.startswith("Zo maak je het") + ).next_sibling.next_sibling.next_sibling.next_sibling + instructions = [ + instruction.text + for instruction in instructions_table + if instruction.text.strip() + ] + return "\n".join(instructions).strip() + + def ratings(self): + # Ratings do not exist on this site + return None + + def cuisine(self): + # Not listed on site + return None + + def description(self): + # Get the recipe's content start. The recipe will start with the description until + # we reach the instructions. + content_start = self.soup.find("div", {"class", "entry-content"}) + + description = "" + for content_element in content_start.children: + # If we reach this, the ingredients are listed and the description is complete + if content_element.text.startswith("Dit heb je nodig"): + break + + description += content_element.text + + return description.strip() diff --git a/tests/test_data/projectgezond.testhtml b/tests/test_data/projectgezond.testhtml new file mode 100644 index 000000000..5a30f1de8 --- /dev/null +++ b/tests/test_data/projectgezond.testhtml @@ -0,0 +1,834 @@ + + + + + + + + +Boeuf bourguignon | Project Gezond + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + + +
+ + +
+ +
+ + +
+ +
+ Diner Kerstrecepten + +

Boeuf bourguignon

+ +
+ + + + + +
+ +
+ + + + + +
+ + +

Deze klassieker vindt zijn oorsprong in de Franse keuken. ‘Rund op bourgondische wijze’ is een vertaling van ‘Boeuf bourguignon’ die niets aan de verbeelding overlaat.

+ + + +

Dit recept is dan ook het perfecte antwoord als het weer tijd is voor een potje stoof!

+ + + +

Want het is verre van moeilijk om deze ultieme stoofpot te bereiden. Je hebt enkel wat (wacht)tijd en dus geduld nodig. Het is helemaal geen gek idee dat je dit recept al de dag van tevoren klaarmaakt trouwens. De smaken kunnen dan zelfs nog beter intrekken.

+ + + +

Als dat geen ‘Boeuf bourguignon’ wordt…

+ + + +

Dit heb je nodig (twee personen)

+ + + +
  • 40 gr ontbijtspek
  • 250 gr runderriblappen
  • 10 gr bloem
  • 1 ui
  • 150 gr winterpeen
  • 1 teentje knoflook
  • 35 gr tomatenpuree
  • 100 ml rode wijn
  • 200 ml runderbouillon
  • 1 laurierblaadje
  • 1 takje tijm
  • 1 kruidnagel
  • 150 gr champignons
  • 50 gr zilveruitjes
+ + + +

Zo maak je het

+ + + +

Bereidingstijd: 30 minuten + 2 uur stoven

+ + + +
  • Bak de plakken ontbijtspek bruin en licht krokant in een droge (stoof)pan. Haal uit de pan en zorg dat het bakvet achterblijft.
  • Snijd de runderriblappen in blokjes van 2 bij 2 centimeter. Bestrooi met peper, zout en de bloem. Schep om tot alles goed verdeeld is.
  • Snijd de ui in halve ringen en de winterpeen in plakken.
  • Hak de knoflook fijn.
  • Verwarm de pan waar het ontbijtspek in gebakken is opnieuw. Bak de riblappen op hoog vuur rondom bruin.
  • Gebruik indien nodig een klein beetje boter of olijfolie.
  • Voeg de ui en winterpeen toe en bak enkele minuten mee met de blokjes vlees.
  • Zet het vuur lager en voeg de knoflook toe. Bak 1 à 2 minuten mee. Voeg de tomatenpuree toe. Roer los en bak 2 à 3 minuten mee.
  • Blus af met de rode wijn. Roer eventuele aanbaksels los van de bodem. Laat de wijn grotendeels verdampen.
  • Voeg de runderbouillon, het laurierblaadje, het takje tijm en de kruidnagel toe.
  • Snijd de plakken ontbijtspek in stukjes en voeg toe.
  • Laat het gerecht ongeveer 2 uur stoven met de deksel op de pan.
  • Boen de champignons schoon en snijd ze in kwarten.
  • Snijd de zilveruitjes doormidden.
  • Voeg de champignons en de zilveruitjes toe.
  • Laat alles nog minimaal 30 minuten stoven. Doe dit eventueel zonder deksel op de pan, zodat de boeuf bourguignon wat verder inkookt.
  • Haal het laurierblaadje, het takje tijm en de kruidnagel uit de pan.
+ + + +

Tips en tricks

+ + + +
  • Haal het vlees minimaal een half uur voor het bakken uit de koelkast.
  • Voeg aan het begin van het stoofproces een scheutje vocht van de zilveruitjes toe. Een scheutje azijn kan ook. Het zuur breekt bindweefsel af en dat komt de malsheid van het vlees ten goede.
  • Laat het gerecht gerust een extra uurtje stoven. Hoe langer je het vlees stooft, hoe zachter het wordt.
  • Lekker met een portie stoofpeertjes!
+ + + +

Voedingswaarde (per persoon)

+ + + +
  • Kcal: 428
  • Eiwit: 33 gram
  • Koolhydraten: 21 gram
  • Vet: 19 gram
  • Vezels: 8 gram
+ + + +

Eet smakelijk!

+
+ + +
+
+
+
+ + + + +
+ + +
+ + + + + + + + + + +
+
+

16 reacties

+ +
+ +
+
+
+ +
+

Laat een reactie achter

+ +

+ +

+ +

+ + + +
+ +
+ +
+ + + +
+ + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/test_projectgezond.py b/tests/test_projectgezond.py new file mode 100644 index 000000000..3b669059e --- /dev/null +++ b/tests/test_projectgezond.py @@ -0,0 +1,72 @@ +# mypy: allow-untyped-defs + +from recipe_scrapers.projectgezond import ProjectGezond +from tests import ScraperTest + + +class TestProjectGezondScraper(ScraperTest): + + scraper_class = ProjectGezond + + def test_host(self): + self.assertEqual("projectgezond.nl", self.harvester_class.host()) + + def test_author(self): + self.assertEqual("Project Gezond", self.harvester_class.author()) + + def test_title(self): + self.assertEqual("Boeuf bourguignon", self.harvester_class.title()) + + def test_category(self): + self.assertEqual("Diner, Kerstrecepten", self.harvester_class.category()) + + def test_total_time(self): + self.assertEqual("30 minuten + 2 uur stoven", self.harvester_class.total_time()) + + def test_yields(self): + self.assertEqual("twee personen", self.harvester_class.yields()) + + def test_image(self): + self.assertEqual( + "https://www.projectgezond.nl/wp-content/uploads/2021/11/BoeufBourguignon-768x1024.jpg", + self.harvester_class.image(), + ) + + def test_ingredients(self): + self.assertEqual( + [ + "40 gr ontbijtspek", + "250 gr runderriblappen", + "10 gr bloem", + "1 ui", + "150 gr winterpeen", + "1 teentje knoflook", + "35 gr tomatenpuree", + "100 ml rode wijn", + "200 ml runderbouillon", + "1 laurierblaadje", + "1 takje tijm", + "1 kruidnagel", + "150 gr champignons", + "50 gr zilveruitjes", + ], + self.harvester_class.ingredients(), + ) + + def test_instructions(self): + self.assertEqual( + "Bak de plakken ontbijtspek bruin en licht krokant in een droge (stoof)pan. Haal uit de pan en zorg dat het bakvet achterblijft.\nSnijd de runderriblappen in blokjes van 2 bij 2 centimeter. Bestrooi met peper, zout en de bloem. Schep om tot alles goed verdeeld is. \nSnijd de ui in halve ringen en de winterpeen in plakken.\nHak de knoflook fijn. \nVerwarm de pan waar het ontbijtspek in gebakken is opnieuw. Bak de riblappen op hoog vuur rondom bruin. \nGebruik indien nodig een klein beetje boter of olijfolie. \nVoeg de ui en winterpeen toe en bak enkele minuten mee met de blokjes vlees.\nZet het vuur lager en voeg de knoflook toe. Bak 1 à 2 minuten mee. Voeg de tomatenpuree toe. Roer los en bak 2 à 3 minuten mee.\nBlus af met de rode wijn. Roer eventuele aanbaksels los van de bodem. Laat de wijn grotendeels verdampen.\nVoeg de runderbouillon, het laurierblaadje, het takje tijm en de kruidnagel toe.\nSnijd de plakken ontbijtspek in stukjes en voeg toe.\nLaat het gerecht ongeveer 2 uur stoven met de deksel op de pan. \nBoen de champignons schoon en snijd ze in kwarten. \nSnijd de zilveruitjes doormidden. \nVoeg de champignons en de zilveruitjes toe.\nLaat alles nog minimaal 30 minuten stoven. Doe dit eventueel zonder deksel op de pan, zodat de boeuf bourguignon wat verder inkookt. \nHaal het laurierblaadje, het takje tijm en de kruidnagel uit de pan.", + self.harvester_class.instructions(), + ) + + def test_ratings(self): + self.assertEqual(None, self.harvester_class.ratings()) + + def test_cuisine(self): + self.assertEqual(None, self.harvester_class.cuisine()) + + def test_description(self): + self.assertEqual( + "Deze klassieker vindt zijn oorsprong in de Franse keuken. ‘Rund op bourgondische wijze’ is een vertaling van ‘Boeuf bourguignon’ die niets aan de verbeelding overlaat.\nDit recept is dan ook het perfecte antwoord als het weer tijd is voor een potje stoof!\nWant het is verre van moeilijk om deze ultieme stoofpot te bereiden. Je hebt enkel wat (wacht)tijd en dus geduld nodig. Het is helemaal geen gek idee dat je dit recept al de dag van tevoren klaarmaakt trouwens. De smaken kunnen dan zelfs nog beter intrekken.\nAls dat geen ‘Boeuf bourguignon’ wordt…", + self.harvester_class.description(), + )