Skip to content

Commit

Permalink
Merge branch 'main' into v14
Browse files Browse the repository at this point in the history
  • Loading branch information
jayaddison committed Sep 9, 2024
2 parents 1efd538 + a83ba60 commit b9e39d7
Show file tree
Hide file tree
Showing 3 changed files with 1,499 additions and 827 deletions.
102 changes: 27 additions & 75 deletions recipe_scrapers/projectgezond.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re

from ._abstract import AbstractScraper
from ._exceptions import FieldNotProvidedByWebsiteException


class ProjectGezond(AbstractScraper):
Expand All @@ -11,82 +12,33 @@ def host(cls):
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 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
raise FieldNotProvidedByWebsiteException(return_value=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
raise FieldNotProvidedByWebsiteException(return_value=None)

description += content_element.text

return description.strip()
def category(self):
category_script = self.soup.find(
"script", string=re.compile("var dataLayer_content =")
)
if not category_script:
return None

category_text = category_script.string
start = category_text.find('"pageCategory":[')
if start != -1:
start += len('"pageCategory":[')
end = category_text.find("]", start)
if end != -1:
categories = category_text[start:end].strip('"').split('","')
return categories if categories else None

def nutrients(self):
nutrient_info = {}
nutrient_elements = self.soup.select("details.nutritions div.nutrition")
for element in nutrient_elements:
key = element.get("itemprop")
value = element.find("dt").get_text(strip=True)
nutrient_info[key] = value
return nutrient_info
46 changes: 28 additions & 18 deletions tests/test_data/projectgezond.nl/projectgezond.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"author": "Project Gezond",
"canonical_url": "https://www.projectgezond.nl/boeuf-bourguignon/",
"canonical_url": "https://www.projectgezond.nl/recepten/boeuf-bourguignon",
"site_name": "Project Gezond",
"host": "projectgezond.nl",
"language": "nl",
"language": "nl-NL",
"title": "Boeuf bourguignon",
"ingredients": [
"40 gr ontbijtspek",
Expand All @@ -14,7 +14,7 @@
"1 teentje knoflook",
"35 gr tomatenpuree",
"100 ml rode wijn",
"200 ml runderbouillon",
"200 ml rundrbouillon",
"1 laurierblaadje",
"1 takje tijm",
"1 kruidnagel",
Expand All @@ -23,28 +23,38 @@
],
"instructions_list": [
"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 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. ",
"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. ",
"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. ",
"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."
],
"category": "Alle recepten uit ons kookboek 'Altijd lekker', Diner, Kerstrecepten",
"yields": "twee personen",
"description": "Wist je dat dit recept ook te vinden is in ons bestseller kookboek ‘Altijd lekker’? In dit boek vind je een selectie van 100 populaire recepten uit ons online afslankprogramma. Benieuwd naar alle recepten uit dit boek? Bekijk dan deze pagina.\nDeze 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…",
"total_time": "30 minuten + 2 uur stoven",
"cuisine": null,
"ratings": null,
"image": "https://www.projectgezond.nl/wp-content/uploads/2021/11/BoeufBourguignon-768x1024.jpg"
"category": [
"altijd-lekker",
"diner",
"kerst"
],
"yields": "2 servings",
"description": "Wist je dat dit recept ook te vinden is in ons bestseller kookboek ‘Altijd lekker’? In dit boek vind je een selectie van 100 populaire recepten uit ons online afslankprogramma. Benieuwd naar alle recepten uit dit boek? Bekijk dan deze pagina. 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…",
"total_time": 150,
"prep_time": 30,
"nutrients": {
"calories": "428",
"fatContent": "19 gram",
"carbohydrateContent": "21 gram",
"proteinContent": "33 gram",
"fiberContent": "8 gram"
},
"image": "https://www.projectgezond.nl/content/uploads/2021/11/BoeufBourguignon-scaled-1.jpg"
}
Loading

0 comments on commit b9e39d7

Please sign in to comment.