Skip to content

Commit

Permalink
Fixup: repair sallys-blog to match updated website design (#744)
Browse files Browse the repository at this point in the history
  • Loading branch information
jayaddison committed Mar 14, 2023
1 parent 6e4d634 commit ec73224
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ Scrapers available for:
- `https://rosannapansino.com <https://rosannapansino.com>`_
- `https://rutgerbakt.nl/ <https://rutgerbakt.nl/>`_
- `https://sallysbakingaddiction.com <https://sallysbakingaddiction.com/>`_
- `https://sallys-blog.de <https://sallys-blog.de/>`_
- `https://www.saveur.com/ <https://www.saveur.com/>`_
- `https://seriouseats.com/ <https://seriouseats.com>`_
- `https://simple-veganista.com/ <https://simple-veganista.com/>`_
Expand Down
2 changes: 2 additions & 0 deletions recipe_scrapers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@
from .rosannapansino import RosannaPansino
from .rutgerbakt import RutgerBakt
from .sallysbakingaddiction import SallysBakingAddiction
from .sallysblog import SallysBlog
from .saveur import Saveur
from .seriouseats import SeriousEats
from .simpleveganista import SimpleVeganista
Expand Down Expand Up @@ -438,6 +439,7 @@
RosannaPansino.host(): RosannaPansino,
RutgerBakt.host(): RutgerBakt,
SallysBakingAddiction.host(): SallysBakingAddiction,
SallysBlog.host(): SallysBlog,
Saveur.host(): Saveur,
SeriousEats.host(): SeriousEats,
SimpleVeganista.host(): SimpleVeganista,
Expand Down
2 changes: 1 addition & 1 deletion recipe_scrapers/plugins/opengraph_image_fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ def decorated_method_wrapper(self, *args, **kwargs):
image = self.soup.find(
"meta", {"property": "og:image", "content": True}
)
return image.get("content")
return image.get("content") if image else None

return decorated_method_wrapper
56 changes: 56 additions & 0 deletions recipe_scrapers/sallysblog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from ._abstract import AbstractScraper
from ._utils import get_minutes, normalize_string


class SallysBlog(AbstractScraper):
@classmethod
def host(cls):
return "sallys-blog.de"

def title(self):
return normalize_string(self.soup.head.find("title").get_text())

def image(self):
raise NotImplementedError() # todo: probably better to return URLs than base64 content

def total_time(self):
heading = self.soup.find("p", string="Zubereitungszeit")
timing = heading.find_next_sibling("h6")
return get_minutes(timing.text)

def _servings_heading(self):
return self.soup.find("h4", string="Zutaten für:")

def yields(self):
servings_heading = self._servings_heading()
servings = servings_heading.find_next_sibling("div").find("input")
return servings["value"]

def _groupings(self):
servings_heading = self._servings_heading()
ingredients_area = servings_heading.next_sibling.next_sibling
return ingredients_area.find_all("div", recursive=False)

def ingredients(self):
descriptions = []
for grouping in self._groupings():
ingredients = grouping.find_all("div", recursive=False)
for ingredient in ingredients:
descriptions.append(ingredient.text)

return [normalize_string(description) for description in descriptions]

def instructions(self):
grouping_titles = {grouping.find("h5").text for grouping in self._groupings()}
uppercase_titles = self.soup.find_all("h2", {"class": "uppercase"})

descriptions = []
for title in uppercase_titles:
if title.text in grouping_titles or title.text.endswith("fertigstellen"):
instructions = title.find_next_sibling("div").find_all("p")
for instruction in instructions:
descriptions.append(instruction.text)

return "\n".join(
[normalize_string(description) for description in descriptions]
)
1 change: 1 addition & 0 deletions tests/test_data/sallysblog.testhtml

Large diffs are not rendered by default.

63 changes: 63 additions & 0 deletions tests/test_sallysblog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from recipe_scrapers.sallysblog import SallysBlog
from tests import ScraperTest


class TestSallysBlogScraper(ScraperTest):
scraper_class = SallysBlog

def test_host(self):
self.assertEqual("sallys-blog.de", self.harvester_class.host())

def test_canonical_url(self):
self.assertEqual(
"https://sallys-blog.de/rezepte/20-minuten-pasta-brokkoli-schinken-nudeln",
self.harvester_class.canonical_url(),
)

def test_title(self):
self.assertEqual(
self.harvester_class.title(),
"20 Minuten Pasta / Brokkoli-Schinken-Nudeln / Sally und Murat kochen",
)

def test_total_time(self):
self.assertEqual(20, self.harvester_class.total_time())

def test_yields(self):
self.assertEqual("6", self.harvester_class.yields())

def test_image(self):
pass # todo

def test_ingredients(self):
self.assertEqual(
[
"1 Zwiebel",
"1 Knoblauchzehe",
"20 g Butter",
"20 g Mehl",
"300 g Gemüsebrühe",
"200 g Milch",
"500 g Brokkoli",
"200 g Gorgonzola",
"50 g Parmesan",
"100 g Schinken (z. B. Pute)",
"150 g Erbsen (TK)",
"0,25 TL Salz",
"0,25 TL Pfeffer",
"500 g Nudeln (z. B. Orechiette)",
],
self.harvester_class.ingredients(),
)

def test_instructions(self):
return self.assertEqual(
"\n".join(
[
"Schäle die Zwiebel und Knoblauchzehe und schneide sie fein. Erhitze die Butter in einer großen Pfanne und gib das Mehl hinzu. Brate es etwa 1 Minute an. Füge die Knoblauch- und Zwiebelwürfel hinzu und brate sie auch etwa 2-3 Minuten an. Lasse in der Zwischenzeit Wasser für die Nudeln aufkochen und salze es gut.",
"Lösche die Mehlschwitze mit der Gemüsebrühe und Milch ab und lasse die Soße aufkochen. Teile die Röschen des Brokkolis auf, schäle und schneide den Strunk fein. Gib die Strunkwürfel und die beiden Käsesorten grob zerkleinert in die Soße, würze sie mit Salz und Pfeffer und lasse sie mit Deckel etwa 2 Minuten köcheln.",
"Schneide den Schinken in Würfel und gib ihn mit den Brokkoliröschen und den Erbsen in die Soße und lasse den Brokkoli etwa 3-4 Minuten in der Soße köcheln. Gib etwa 1 Schöpfkelle Nudelwasser in die Soße, gieße die Nudeln ab und vermische sie mit der Soße. Fertig ist das schnelle Nudelgericht. Viel Spaß beim Nachkochen, eure Sally!",
]
),
self.harvester_class.instructions(),
)

0 comments on commit ec73224

Please sign in to comment.