-
Notifications
You must be signed in to change notification settings - Fork 559
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Add scraper support for spisbedre.dk (#1486) * Reorder JSON unit tests
- Loading branch information
1 parent
371a663
commit 74c5de2
Showing
6 changed files
with
1,826 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import json | ||
|
||
from ._abstract import AbstractScraper | ||
from ._grouping_utils import IngredientGroup | ||
|
||
|
||
class SpisBedre(AbstractScraper): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.recipe_json = json.loads( | ||
self.soup.find("div", id="app").attrs["data-page"] | ||
)["props"]["recipe"] | ||
|
||
@classmethod | ||
def host(cls): | ||
return "spisbedre.dk" | ||
|
||
def author(self): | ||
return self.schema.author() | ||
|
||
def title(self): | ||
return self.schema.title() | ||
|
||
def category(self): | ||
return ", ".join([type["name"] for type in self.recipe_json.get("tags", [])]) | ||
|
||
def total_time(self): | ||
return self.schema.total_time() | ||
|
||
def yields(self): | ||
return self.schema.yields() | ||
|
||
def ingredients(self): | ||
result = [] | ||
for ingredient_group in self.ingredient_groups(): | ||
result.extend(ingredient_group.ingredients) | ||
return result | ||
|
||
def ingredient_groups(self): | ||
result = [] | ||
servings = self.recipe_json.get("serving_size", 1) | ||
|
||
def format_ingredient(servings, ingredient): | ||
ingredient_elements = [] | ||
|
||
def ingredient_label(amount, inflection, ingredient, prefix, suffix): | ||
label = [] | ||
if ingredient is None: | ||
return None | ||
|
||
if prefix: | ||
label.append(prefix) | ||
|
||
if inflection in ["singular", "plural"]: | ||
label.append(ingredient.get("name_" + inflection)) | ||
elif amount and amount > 0 and amount < 2: | ||
label.append(ingredient.get("name_singular")) | ||
else: | ||
label.append(ingredient.get("name_plural")) | ||
|
||
if suffix: | ||
label.append(suffix) | ||
|
||
return " ".join(label) | ||
|
||
def unit_label(amount, inflection, texts): | ||
label = [] | ||
if amount is None or texts is None: | ||
return None | ||
|
||
if texts.get("abbreviation"): | ||
label.append(texts.get("abbreviation")) | ||
elif inflection in ["singular", "plural"]: | ||
label.append(texts.get("name_" + inflection)) | ||
elif amount > 0 and amount < 2: | ||
label.append(texts.get("name_singular")) | ||
else: | ||
label.append(texts.get("name_plural")) | ||
|
||
return " ".join(label) | ||
|
||
total_amount = amount = ingredient.get("amount") | ||
if amount: | ||
total_amount = amount * servings | ||
if int(total_amount) == total_amount: | ||
total_amount = int(total_amount) | ||
ingredient_elements.append(str(total_amount)) | ||
|
||
# For some reason unit_id 21 isn't rendered on the site, so we filter it as well | ||
if ingredient.get("unit_id") != 21: | ||
unit = unit_label( | ||
total_amount, | ||
ingredient.get("unit_inflection"), | ||
ingredient.get("unit"), | ||
) | ||
if unit: | ||
ingredient_elements.append(unit) | ||
|
||
label = ingredient_label( | ||
total_amount, | ||
ingredient.get("ingredient_inflection"), | ||
ingredient.get("ingredient"), | ||
ingredient.get("prefix"), | ||
ingredient.get("suffix"), | ||
) | ||
if label: | ||
ingredient_elements.append(label) | ||
|
||
return " ".join(ingredient_elements) | ||
|
||
for group in self.recipe_json.get("grouped_ingredients", []): | ||
current_group = {"ingredients": [], "purpose": group.get("title")} | ||
for ingredient in group.get("ingredients", []): | ||
formatted_ingredient = format_ingredient(servings, ingredient) | ||
if formatted_ingredient: | ||
current_group["ingredients"].append(formatted_ingredient) | ||
|
||
result.append(current_group) | ||
|
||
return [ | ||
IngredientGroup( | ||
ingredient_group["ingredients"], ingredient_group["purpose"] | ||
) | ||
for ingredient_group in result | ||
] | ||
|
||
def instructions(self): | ||
result = [] | ||
for group in self.recipe_json.get("grouped_instructions", []): | ||
for instruction in group.get("instructions", []): | ||
if instruction.get("instruction"): | ||
result.append(instruction.get("instruction")) | ||
|
||
return "\n".join(result) | ||
|
||
def ratings(self): | ||
return self.schema.ratings() | ||
|
||
def cuisine(self): | ||
return self.schema.cuisine() | ||
|
||
def description(self): | ||
return self.schema.description() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
{ | ||
"author": "Louisa Lorang", | ||
"canonical_url": "https://spisbedre.dk/opskrifter/kyllingetaerte-med-butterdejslag", | ||
"site_name": "SPIS BEDRE", | ||
"host": "spisbedre.dk", | ||
"language": "da", | ||
"title": "Kyllingetærte med butterdejslåg", | ||
"ingredients": [ | ||
"2 stilke bladselleri", | ||
"2 gulerødder", | ||
"1 porre", | ||
"2 fed hvidløg", | ||
"2 spsk. olivenolie til stegning", | ||
"salt og peber", | ||
"50 g smør", | ||
"50 g hvedemel", | ||
"2 dl hønsebouillon", | ||
"2 dl piskefløde", | ||
"300 g kogt kyllingebrystfilet", | ||
"200 g ærter fra frost", | ||
"1 spsk. frisk timian", | ||
"1 rulle butterdej", | ||
"1 æg til pensling" | ||
], | ||
"ingredient_groups": [ | ||
{ | ||
"ingredients": [ | ||
"2 stilke bladselleri", | ||
"2 gulerødder", | ||
"1 porre", | ||
"2 fed hvidløg", | ||
"2 spsk. olivenolie til stegning", | ||
"salt og peber", | ||
"50 g smør", | ||
"50 g hvedemel", | ||
"2 dl hønsebouillon", | ||
"2 dl piskefløde", | ||
"300 g kogt kyllingebrystfilet", | ||
"200 g ærter fra frost", | ||
"1 spsk. frisk timian", | ||
"1 rulle butterdej", | ||
"1 æg til pensling" | ||
], | ||
"purpose": null | ||
} | ||
], | ||
"instructions_list": [ | ||
"Rens bladselleri, og skær dem i tynde skiver. Skrub eller skræl gulerødderne, og skær dem i tern. Rens porre, og pil hvidløg. Hak begge dele fint.", | ||
"Steg alle grøntsagerne i olie i en stor, dyb pande. De skal ikke tage farve, men falde let sammen. Krydr dem med salt og peber. Tag grøntsagerne af panden, og læg dem til side på en stor tallerken.", | ||
"Smelt smør i den samme pande. Pisk mel i. Tilsæt langsomt bouillon under piskning. Pisk, til saucen er glat. Tilsæt fløde, og lad saucen simre i 4-5 minutter.", | ||
"Tænd ovnen på 220°. Skær kyllingebrystfilet i strimler. Vend kyllingestrimler, grøntsager og ærter i saucen. Skyl og pluk timian. Kog saucen op, og smag til med timian, salt og peber.", | ||
"Fordel fyldet i en tærteform. Rul butterdejen ud, og læg den forsigtigt over fyldet. Klem overskydende dej sammen rundt i kanten. Klip et par små huller i midten af butterdejslåget, så damp kan slippe ud.", | ||
"Pisk æg med 1½ spsk. koldt vand, og pensl butterdejslåget. Bag tærten i ovnen i ca. 20 minutter, til den er gylden og lækker. Servér den lun, evt. med salat til." | ||
], | ||
"category": "Hovedretter", | ||
"yields": "4 servings", | ||
"description": "Brug dine grøntsags- og kyllingerester i en lun tærte til middagsbordet. Det sprøde butterdejslåg er prikken over i'et.", | ||
"total_time": 40, | ||
"image": "https://spisbedre-production-app.imgix.net/images/recipes/kyllingetaerte-med-butterdejslag_15964.jpg?fit=crop&crop=focalpoint&fp-x=0.44097082638046&fp-y=0.66429758726712&fp-z=1.25" | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
{ | ||
"author": "Timm Vladimir", | ||
"canonical_url": "https://spisbedre.dk/opskrifter/stegt-makrel-med-kartofler", | ||
"site_name": "SPIS BEDRE", | ||
"host": "spisbedre.dk", | ||
"language": "da", | ||
"title": "Stegt makrel med kartofler", | ||
"ingredients": [ | ||
"4 ferske makrelfileter", | ||
"100 g smør", | ||
"300 g stikkelsbær", | ||
"1 dl vand", | ||
"1 dl eddike", | ||
"1 dl sukker", | ||
"600 g små kartofler", | ||
"1 bundt frisk dild", | ||
"salt", | ||
"2 hjertesalater", | ||
"1 spsk. smagsneutral olie til stegning" | ||
], | ||
"ingredient_groups": [ | ||
{ | ||
"ingredients": [ | ||
"4 ferske makrelfileter", | ||
"100 g smør" | ||
], | ||
"purpose": null | ||
}, | ||
{ | ||
"ingredients": [ | ||
"300 g stikkelsbær", | ||
"1 dl vand", | ||
"1 dl eddike", | ||
"1 dl sukker" | ||
], | ||
"purpose": "Syltede stikkelsbær" | ||
}, | ||
{ | ||
"ingredients": [ | ||
"600 g små kartofler", | ||
"1 bundt frisk dild", | ||
"salt", | ||
"2 hjertesalater", | ||
"1 spsk. smagsneutral olie til stegning" | ||
], | ||
"purpose": "Tilbehør" | ||
} | ||
], | ||
"instructions_list": [ | ||
"Skyl stikkelsbærrene, og hæld dem i et skoldet glas. Kog vand, eddike og sukker op i en lille gryde, og hæld den kogende lage over bærrene.", | ||
"Luk glasset til, og lad bærrene stå 1-2 døgn.", | ||
"Skrub kartoflerne, og læg dem i en gryde. Skyl dild, og skær stilkene fra (gem toppene til pynt). Læg stilkene ned til kartoflerne, hæld vand og lidt salt på, og kog kartoflerne, til de er møre.", | ||
"Skyl hjertesalater, og skær dem over på langs. Steg dem i lidt olie på en pande i ca. 1 minut, til de har taget lidt farve.", | ||
"Filetér makrellerne. Steg dem i lidt smør på en pande i ca. 3 minutter på skindsiden. Vend dem, og steg dem i 1 minut på kødsiden.", | ||
"Smelt resten af smørret på panden, til det er brunet. Anret makrelfileterne på tallerkener sammen med kogte kartofler, stegt hjertesalat, brunet smør og dild. Servér de syltede stikkelsbær til." | ||
], | ||
"category": "Hovedretter, Frokost, Dansk", | ||
"yields": "4 servings", | ||
"description": "Hvad enten der er tale om frokost eller aftensmad, kan du altid spise stegt makrel med møre kartofler toppet med surt og sødt.", | ||
"total_time": 35, | ||
"ratings": 4.0, | ||
"image": "https://spisbedre-production-app.imgix.net/images/recipes/stegt-makrel-med-kartofler_324.jpg?fit=crop&crop=focalpoint&fp-x=0.5&fp-y=0.63232421875&fp-z=1" | ||
} |
1,230 changes: 1,230 additions & 0 deletions
1,230
tests/test_data/spisbedre.dk/spisbedre_2.testhtml
Large diffs are not rendered by default.
Oops, something went wrong.