Repository: hhursev/recipe-scrapers

Issue:
schema.org author retrieval: author from WebPage not returned
**Pre-filing checks**

- [x] I have searched for open issues that report the same problem
- [x] I have checked that the bug affects the latest version of the library

**The URL of the recipe(s) that are not being scraped correctly**

- https://www.rewe.de/rezepte/wintergemuese-gnocchi-pfanne-kraeuterdip/

Discovered during discussion at https://github.com/hhursev/recipe-scrapers/pull/1378#discussion_r1840366059

**The results you expect to see**

The author name should be available from `schema.org` metadata on the recipe page, by accessing the `author` field - in particular the `WebPage` item.

**The results (including any Python error messages) that you are seeing**

The `author` field returns a null/empty value.

Discussion:

Patch:
diff --git a/.flake8 b/.flake8
index d3e86fd9..76661ede 100644
--- a/.flake8
+++ b/.flake8
@@ -3,7 +3,7 @@
 # and would error on `str.format()` usage
 ignore = E203, E501, W503, FS002, N818
 max-line-length = 88
-max-complexity = 20
+max-complexity = 21
 select = B,C,E,F,N,W,T4,B9
 exclude =
     ./.tox/
diff --git a/recipe_scrapers/_schemaorg.py b/recipe_scrapers/_schemaorg.py
index 94ceb39d..c1d6a4b7 100644
--- a/recipe_scrapers/_schemaorg.py
+++ b/recipe_scrapers/_schemaorg.py
@@ -79,31 +79,34 @@ class SchemaOrg:
                         self.ratingsdata[rating_id] = rating
 
         for syntax in SYNTAXES:
-            # Make sure entries of type Recipe are always parsed first
-            syntax_data = data.get(syntax, [])
-            try:
-                index = [x.get("@type", "") for x in syntax_data].index("Recipe")
-                syntax_data.insert(0, syntax_data.pop(index))
-            except ValueError:
-                pass
-
-            for item in syntax_data:
+            for item in data.get(syntax, []):
                 if SCHEMA_ORG_HOST not in item.get("@context", ""):
                     continue
 
                 # If the item itself is a recipe, then use it directly as our datasource
                 if recipe := self._find_entity(item, "Recipe"):
-                    self.format = syntax
-                    self.data = recipe
-                    return
-
+                    pass
                 # If the item is a webpage and describes a recipe entity, use the entity as our datasource
-                if self._contains_schematype(item, "WebPage"):
-                    main_entity = item.get("mainEntity", {})
-                    if self._contains_schematype(main_entity, "Recipe"):
+                elif self._contains_schematype(item, "WebPage") and (
+                    recipe := item.get("mainEntity", {})
+                ):
+                    pass
+                else:
+                    continue
+                if not self._contains_schematype(recipe, "Recipe"):
+                    continue
+
+                self.data = self.data or recipe
+                for prop in ("@id", "name"):
+                    existing_value = self.data.get(prop)
+                    encountered_value = recipe.get(prop)
+                    if existing_value and encountered_value == existing_value:
+                        if syntax != self.format:
+                            pass  # TODO: single recipe represented using multiple formats; what should we do?
                         self.format = syntax
-                        self.data = main_entity
-                        return
+                        self.data.update(
+                            {k: self.data.get(k, v) for k, v in recipe.items()}
+                        )
 
     def site_name(self):
         if not self.website_name:
diff --git a/recipe_scrapers/miljuschka.py b/recipe_scrapers/miljuschka.py
index 50879a42..edaed2a5 100644
--- a/recipe_scrapers/miljuschka.py
+++ b/recipe_scrapers/miljuschka.py
@@ -7,39 +7,6 @@ class Miljuschka(AbstractScraper):
     def host(cls):
         return "miljuschka.nl"
 
-    def author(self):
-        return self.schema.author()
-
-    def title(self):
-        return self.schema.title()
-
-    def category(self):
-        return self.schema.category()
-
-    def total_time(self):
-        return self.schema.total_time()
-
-    def yields(self):
-        return self.schema.yields()
-
-    def image(self):
-        return self.schema.image()
-
-    def ingredients(self):
-        return self.schema.ingredients()
-
-    def instructions(self):
-        return self.schema.instructions()
-
-    def ratings(self):
-        return self.schema.ratings()
-
-    def cuisine(self):
-        return self.schema.cuisine()
-
-    def description(self):
-        return self.schema.description()
-
     def ingredient_groups(self):
         return group_ingredients(
             self.ingredients(),


Test patch:
diff --git a/tests/library/test_schemaorg.py b/tests/library/test_schemaorg.py
new file mode 100644
index 00000000..f36fc97c
--- /dev/null
+++ b/tests/library/test_schemaorg.py
@@ -0,0 +1,72 @@
+import unittest
+
+from recipe_scrapers._schemaorg import SchemaOrg
+
+JSONLD_PAGE_TEMPLATE = """
+<html>
+<head>
+<link href="http://recipe.test/template" type="canonical" />
+<script type="application/ld+json">{jsonld}</script>
+</head>
+</html>
+"""
+
+SIMPLE_SCHEMA = """
+{
+  "@context": "https://schema.org",
+  "@type": "Recipe",
+  "name": "Test Recipe",
+  "recipeIngredient": ["1 slice of bread", "5g margarine"],
+  "recipeInstructions": ["spread the margarine on the bread"]
+}
+"""
+
+MULTI_ENTITY_SCHEMA = """
+[
+  {
+    "@context": "https://schema.org",
+    "@type": "Recipe",
+    "@id": "http://recipe.test/template",
+    "name": "Test Recipe",
+  },
+  {
+    "@context": "https://schema.org",
+    "@type": "Recipe",
+    "@id": "http://recipe.test/other",
+    "name": "Another great test recipe",
+  },
+  {
+    "@context": "https://schema.org",
+    "@type": "WebPage",
+    "@id": "http://recipe.test/template",
+    "mainEntity": {
+      "@context": "https://schema.org",
+      "@type": "Recipe",
+      "@id": "http://recipe.test/template",
+      "recipeIngredient": ["1 slice of bread", "5g margarine"],
+      "recipeInstructions": ["spread the margarine on the bread"]
+    }
+  }
+]
+"""
+
+
+class TestSchemaOrg(unittest.TestCase):
+
+    def test_simple(self):
+        page_data = JSONLD_PAGE_TEMPLATE.format(jsonld=SIMPLE_SCHEMA)
+        parser = SchemaOrg(page_data)
+
+        self.assertEqual("Test Recipe", parser.title())
+        self.assertIn("1 slice of bread", parser.ingredients())
+        self.assertIn("5g margarine", parser.ingredients())
+        self.assertEqual("spread the margarine on the bread", parser.instructions())
+
+    def test_multi_entity_aggregation(self):
+        page_data = JSONLD_PAGE_TEMPLATE.format(jsonld=MULTI_ENTITY_SCHEMA)
+        parser = SchemaOrg(page_data)
+
+        self.assertEqual("Test Recipe", parser.title())
+        self.assertIn("1 slice of bread", parser.ingredients())
+        self.assertIn("5g margarine", parser.ingredients())
+        self.assertEqual("spread the margarine on the bread", parser.instructions())
diff --git a/tests/test_data/aldi-sued.de/aldisued.json b/tests/test_data/aldi-sued.de/aldisued.json
index df378039..e822ed14 100644
--- a/tests/test_data/aldi-sued.de/aldisued.json
+++ b/tests/test_data/aldi-sued.de/aldisued.json
@@ -22,28 +22,6 @@
     "1 Prise LE GUSTO Zimt",
     "3 Zweige Bio-Topfkräuter Petersilie"
   ],
-  "ingredient_groups": [
-    {
-      "ingredients": [
-        "1 Bund Suppengemüse (alternativ 2 Möhren, 150 g Knollensellerie, 1/2 Stange Porree)",
-        "1 Zwiebel",
-        "4 EL MILSANI Butter",
-        "2 EL GOLDÄHREN Qualitäts-Weizenmehl Type 405",
-        "500 ml trockener Weißwein",
-        "500 ml LE GUSTO Klare Brühen im Glas, Sorte: Gemüse",
-        "2 Lorbeerblätter (optional)",
-        "200 g MILSANI Sahne",
-        "LE GUSTO Salz",
-        "LE GUSTO Pfeffer",
-        "LE GUSTO Muskat",
-        "DIADEM Zucker",
-        "3 Scheiben GOLDÄHREN Sandwichtoast",
-        "1 Prise LE GUSTO Zimt",
-        "3 Zweige Bio-Topfkräuter Petersilie"
-      ]
-    }
-  ],
-  "instructions": "Das Suppengemüse und die Zwiebel schälen und würfeln.\n2 EL Butter in einem Topf schmelzen und das Gemüse darin andünsten. Das Mehl einstreuen und kurz anschwitzen.\nDen Weißwein und die Brühe eingießen. Ggf. Lorbeerblätter hineingeben. Aufkochen und ca. 20 Minuten köcheln lassen.\nDie Suppe durch ein Sieb streichen und zurück in den Topf geben. Die Sahne eingießen und mit Salz, Pfeffer, Muskat und Zucker abschmecken.\nDas Toastbrot würfeln. 2 EL Butter schmelzen und die Brotwürfel darin goldbraun rösten. Mit Zimt bestreuen.\nDie Petersilie waschen und grob hacken. Die Weinsuppe mit den Zimt-Croûtons und der Petersilie anrichten und servieren.",
   "instructions_list": [
     "Das Suppengemüse und die Zwiebel schälen und würfeln.",
     "2 EL Butter in einem Topf schmelzen und das Gemüse darin andünsten. Das Mehl einstreuen und kurz anschwitzen.",
@@ -56,6 +34,5 @@
   "total_time": 35,
   "cook_time": 20,
   "prep_time": 15,
-  "ratings": 0,
   "image": "https://s7g10.scene7.com/is/image/aldi/202410030128"
 }
diff --git a/tests/test_data/aldi-suisse.ch/aldi-suisse.json b/tests/test_data/aldi-suisse.ch/aldi-suisse.json
index be9c2b53..a1503341 100644
--- a/tests/test_data/aldi-suisse.ch/aldi-suisse.json
+++ b/tests/test_data/aldi-suisse.ch/aldi-suisse.json
@@ -29,35 +29,6 @@
     "Etwas Pfeffer aus der Mühle",
     "etwas Olivenöl"
   ],
-  "ingredient_groups": [
-    {
-      "ingredients": [
-        "400 g Rotkabis",
-        "3 Äpfel",
-        "2 Orangen, Abrieb und Saft",
-        "2 TL Zimt gemahlen",
-        "2 EL Zucker",
-        "Salz",
-        "Etwas Pfeffer aus der Mühle",
-        "400 g Weissmehl",
-        "4 Eier",
-        "200 ml Wasser",
-        "200 g Zucker",
-        "500 g Maroni geschält",
-        "300 ml Apfelschorle",
-        "1 Prise Salz",
-        "500 g Rehgeschnetzeltes",
-        "2 rote Zwiebeln",
-        "250 g Champignons",
-        "250 ml Rotwein",
-        "250 ml Vollrahm",
-        "1 Prise Salz",
-        "Etwas Pfeffer aus der Mühle",
-        "etwas Olivenöl"
-      ]
-    }
-  ],
-  "instructions": "Für das Apfel-Rotkraut den Rotkabis in feine Streifen schneiden, diesen mit grob geraffeltem Apfel, Orangenabrieb, Orangensaft, Zimt, Zucker, Salz und Pfeffer aus der Mühle verkneten und über Nacht im Kühlschrank stehen lassen. Am nächsten Tag in einer Pfanne bei mittlerer Hitze unter gelegentlichem Rühren weichkochen.\nDas Mehl für die Knöpfli in eine Schüssel geben. Eine kleine Mulde formen und die Eier hineingeben. Am besten mit einem Holzlöffel den Teig verrühren, dabei das Wasser langsam dazugiessen. Kräftig rühren und den Teig so lange schlagen, bis er Blasen wirft.\nDen Teig über ein Spätzlisieb geben und ins kochende, gesalzene Wasser drücken. Mehrfach überwallen lassen. Im kalten Wasser abschrecken und über Nacht im Kühlschrank stehen lassen. Am nächsten Tag in einer heissen Pfanne mit etwas Olivenöl goldbraun braten. Mit Salz abschmecken.\nDen Zucker für die Maronis in einer heissen Pfanne karamellisieren. Die Maronis beifügen und rühren. Vorsichtig mit Apfelschorle aufgiessen. Salzen und bei mittlerer Hitze weichkochen. Sollte noch zu viel Flüssigkeit vorhanden sein, die Maronis zur Seite stellen und die Sauce einreduzieren, dann wieder miteinander mischen.\nRehgeschnetzeltes waschen und trocknen. In einer heissen Pfanne mit etwas Olivenöl scharf anbraten.  Noch halbrohes Fleisch aus der Pfanne nehmen und auf einem Teller zur Seite stellen. In derselben Pfanne feingewürfelte Zwiebeln rührbraten. Champignons in Scheiben schneiden und mitbraten. Mit Rotwein ablöschen und etwas einkochen lasen. Mit Vollrahm aufgiessen, Sauce köcheln lassen. Mit Salz und Pfeffer aus der Mühle abschmecken. Kurz vor dem Servieren das Fleisch wieder in die Sauce geben und erneut aufkochen lassen.",
   "instructions_list": [
     "Für das Apfel-Rotkraut den Rotkabis in feine Streifen schneiden, diesen mit grob geraffeltem Apfel, Orangenabrieb, Orangensaft, Zimt, Zucker, Salz und Pfeffer aus der Mühle verkneten und über Nacht im Kühlschrank stehen lassen. Am nächsten Tag in einer Pfanne bei mittlerer Hitze unter gelegentlichem Rühren weichkochen.",
     "Das Mehl für die Knöpfli in eine Schüssel geben. Eine kleine Mulde formen und die Eier hineingeben. Am besten mit einem Holzlöffel den Teig verrühren, dabei das Wasser langsam dazugiessen. Kräftig rühren und den Teig so lange schlagen, bis er Blasen wirft.",
@@ -67,7 +38,6 @@
   ],
   "category": "Recipes CH",
   "yields": "4 servings",
-  "description": "",
   "total_time": 90,
   "cook_time": 60,
   "prep_time": 30,
diff --git a/tests/test_data/hofer.at/hofer.json b/tests/test_data/hofer.at/hofer.json
index a1e28109..07e3f574 100644
--- a/tests/test_data/hofer.at/hofer.json
+++ b/tests/test_data/hofer.at/hofer.json
@@ -20,26 +20,6 @@
     "etwas Knoblauch",
     "etwas GOOD CHOICE Salatmix"
   ],
-  "ingredient_groups": [
-    {
-      "ingredients": [
-        "100 g Weißbrotwürfel",
-        "1 Stk. Zwiebel",
-        "75 ml MILFINA Vollmilch",
-        "1 GOLDLAND Ei",
-        "190 g Kartoffeln, mehlig",
-        "100 g MILFINA Bergkäse",
-        "25 g MILFINA Frischkäse, Sorte: Natur",
-        "etwas Schnittlauch",
-        "etwas Petersilie",
-        "etwas Salz und Pfeffer",
-        "etwas Muskatnuss",
-        "etwas Knoblauch",
-        "etwas GOOD CHOICE Salatmix"
-      ]
-    }
-  ],
-  "instructions": "Die Brotwürfel mit der warmen Milch befeuchten. Bergkäse und Frischkäse klein schneiden und hinzugeben.\nIn der Zwischenzeit die Zwiebeln goldgelb anrösten, damit sie ihren vollen Geschmack entfalten können.\nZwiebeln, gekochte und passierte Kartoffeln, Ei, Kräuter und Gewürze dazugeben und alles gut vermischen. Knödel formen und portionieren.\nKnödel in Fett herausbacken, bis sie goldgelb sind.\nMit grünem Salat angerichtet servieren.",
   "instructions_list": [
     "Die Brotwürfel mit der warmen Milch befeuchten. Bergkäse und Frischkäse klein schneiden und hinzugeben.",
     "In der Zwischenzeit die Zwiebeln goldgelb anrösten, damit sie ihren vollen Geschmack entfalten können.",
diff --git a/tests/test_data/quitoque.fr/quitoque.json b/tests/test_data/quitoque.fr/quitoque.json
index 1d77665d..e3014569 100644
--- a/tests/test_data/quitoque.fr/quitoque.json
+++ b/tests/test_data/quitoque.fr/quitoque.json
@@ -17,25 +17,6 @@
     "vinaigre de votre choix",
     "1 bouillon de poule (cube)"
   ],
-  "ingredient_groups": [
-    {
-      "ingredients": [
-        "4x gousse d'ail (16g)",
-        "8x pomme de terre (1,76kg)",
-        "1x romarin séché (sachet) (5g)",
-        "6x cuisse de canard (1,08kg)",
-        "150 g multifeuille",
-        "qq brins persil plat",
-        "sel",
-        "poivre",
-        "huile d'olive",
-        "vinaigre de votre choix",
-        "1 bouillon de poule (cube)"
-      ],
-      "purpose": null
-    }
-  ],
-  "instructions": "Préchauffez votre four à 220°C en chaleur tournante !\nPendant ce temps, faites chauffer une sauteuse sans matière grasse à feu moyen à vif.\nSaisissez les cuisses de canard 5 à 10 min côté peau puis réservez la sauteuse avec la graisse de canard.\nUne fois grillées, déposez les cuisses de canard dans une cocotte avec un fond d'eau, le romarin et le bouillon de poule. Salez, poivrez.\nCouvrez et enfournez 1h jusqu'à ce qu'elles soient cuites à coeur (la chair n'est plus rose).\nAstuce : ajoutez de l'eau en cours de cuisson si nécessaire et arrosez régulièrement avec le jus de cuisson.\nEn parallèle, faites cuire les pommes de terre.\nÉpluchez et coupez les pommes de terre en rondelles.\nSuggestion : Vous pouvez conserver la peau si vous le souhaitez, pensez à bien les laver et les essuyer.\nDans la sauteuse du canard, faites revenir les pommes de terre 5 min à feu vif sans trop les superposer.\nBaissez sur feu moyen et poursuivez la cuisson 15 min à couvert. Remuez régulièrement pendant la cuisson. Salez, poivrez.\nPendant ce temps, pressez ou hachez l'ail.\nEffeuillez et ciselez le persil.\nAu bout des 15 min, ajoutez l'ail et le persil et poursuivez la cuisson 5 min à couvert.\nAvant de passer à table, assaisonnez la salade d'un filet d'huile d'olive et de vinaigre.",
   "instructions_list": [
     "Préchauffez votre four à 220°C en chaleur tournante !",
     "Pendant ce temps, faites chauffer une sauteuse sans matière grasse à feu moyen à vif.",
diff --git a/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_1.json b/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_1.json
index 87b57059..41bb1d64 100644
--- a/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_1.json
+++ b/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_1.json
@@ -9,7 +9,6 @@
     "350 grams gluten-free flour of choice",
     "Water, as needed, filtered or bottled spring water"
   ],
-  "instructions": "How to make a Gluten Free Sourdough StarterStart: to a clean, sanitized mason jar add 25 grams of gluten free flour and 25 grams warm water (around 77F/25C – 84F/29C). Using a plastic spoon or spatula mix it together. Cover it with cheesecloth and a rubber pan or loosly cover it with the mason jar lid. Allow for it to sit at room temperature at the counter.\n\nFeeding #1: Around 8-12hrs after starting the sourdough starter, add 25 grams of gluten free flour and 25 grams of warm water. Mix it together, loosely cover it and allow for it to see at room temperature . If your mixture seems very stiff, add 5-10 extra grams of water to loosen up the mixture. It’s okay for the starter to be too runny vs being too dry.\n\nFeeding #2: 8-12 hours after the first feeding, it’s time for the second meal. Depending on which flour you used, your may already see some bubbles and growth in your starter. Add 25 grams of flour and 25 grams of warm water, mix, cover and place in a warm place.\n\nFeeding #3: You should definitely see some small bubbles and growth in your gluten free sourdough starter now. Repeat the feeding, mix, cover and store at ambient temperature.\n\nFeeding #4: On day three it's time to switch to a 1:1:1 feeding process and start discarding some of the starter. Remove all but 50 grams of the sourdough starter from the jar. Compost the discard or throw it away. Add 50 grams of fresh flour and 50 grams of warm water (around 77F/25C - 84F/29C) to the jar and mix. Cover and store at ambient temperature. (At this point, it is too early to save the discard for recipes since it is not yet from an established starter. )\n\nFeeding #5 up to 7 days: The sourdough starter should become more active now. You may also see bubbles. Keep up with the feedings every 8-12hrs. Remove all but 50 grams of the sourdough starter from the jar. Compost the discard or throw it away. Add 50 grams of fresh flour and 50 grams of warm water (around 77F/25C - 84F/29C) to the jar and mix. Cover and store at ambient temperature. \n\nAfter Seven days: After seven days and at least three days of consistent growth and doubling the size after every feeding within 4-12 hours, the gluten-free sourdough starter is ready to be used in recipes. I recommend feeding the sourdough starter ONCE a day for an additional week. This will strengthen the starter and build a strong starter to have on hand. I call those feedings maintenance feedings, which can be done with less flour and less often.",
   "instructions_list": [
     "How to make a Gluten Free Sourdough StarterStart: to a clean, sanitized mason jar add 25 grams of gluten free flour and 25 grams warm water (around 77F/25C – 84F/29C). Using a plastic spoon or spatula mix it together. Cover it with cheesecloth and a rubber pan or loosly cover it with the mason jar lid. Allow for it to sit at room temperature at the counter.",
     "Feeding #1: Around 8-12hrs after starting the sourdough starter, add 25 grams of gluten free flour and 25 grams of warm water. Mix it together, loosely cover it and allow for it to see at room temperature . If your mixture seems very stiff, add 5-10 extra grams of water to loosen up the mixture. It’s okay for the starter to be too runny vs being too dry.",
diff --git a/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_2.json b/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_2.json
index 8fb32cb0..245b441d 100644
--- a/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_2.json
+++ b/tests/test_data/theglutenfreeaustrian.com/theglutenfreeaustrian_2.json
@@ -43,7 +43,6 @@
       "purpose": "Cinnamon Sugar"
     }
   ],
-  "instructions": "Cut butter into small cubes and place in a saucepan over medium heat.\nLet the butter melt and then begin cooking. Stir frequently and watch the butter.\nContinue cooking and stirring until the butter starts to smell nutty and turns a medium amber color. Remove from the heat and transfer into the bowl (make sure to get all the brown bits) of your stand mixer and refrigerate for at least 30 minutes in the fridge before proceeding with the gluten free snickerdoodle recipe. The browned butter needs to be solid. It should have the same consistency as room-temperature butter.\nIn a small mixing bowl combine the gluten-free flour, cornstarch, baking soda, cream of tartar, and kosher salt. Whisk to combine and set aside.\nIn the bowl of a stand mixer combine the cooled but still soft browned butter, light brown sugar, and granulated sugar, and beat at medium speed for 4-5 minutes until fluffy and pale. Halfway through, pause to scrape the bowl and beater with a flexible rubber spatula.\nOnce the butter-sugar mixture is light and fluffy, add the room-temperature egg and a teaspoon of vanilla extract. Mix until incorporated. Turn off the mixer and scrape down the sides.\nAdd your dry ingredients and mix until combined. Transfer the dough to an airtight container or cover the mixing bowl and chill the gluten free brown butter snickerdoodles dough for 30-45 minutes.\nWhen ready to bake, preheat your oven to 350F. Line two baking sheets with parchment paper.\nIn a small bowl combine the granulated sugar and ground cinnamon and mix. Scoop medium-sized balls of cookie dough (using a Medium Sized Cookie Scooper) and roll them into cookie dough balls. Roll them in the cinnamon sugar mixture, then place no more than 6-7 of them on the prepared cookie sheets.\nBake them one tray at a time at 350F for 9-11 mins or until they look puffy and light golden brown. I recommend rather underbaking them slightly than overbaking and ending up with dry cookies.\nRemove the snickerdoodles from the oven and allow them to cool for 10 minutes on the sheet pan before transferring them to a wire rack. The cookies will deflate – that is completely normal.\nRepeat with the remaining dough portions.",
   "instructions_list": [
     "Cut butter into small cubes and place in a saucepan over medium heat.",
     "Let the butter melt and then begin cooking. Stir frequently and watch the butter.",
diff --git a/tests/test_data/theloopywhisk.com/theloopywhisk_1.json b/tests/test_data/theloopywhisk.com/theloopywhisk_1.json
index 93996b77..fda545a5 100644
--- a/tests/test_data/theloopywhisk.com/theloopywhisk_1.json
+++ b/tests/test_data/theloopywhisk.com/theloopywhisk_1.json
@@ -16,7 +16,6 @@
     "3/8 - 1/2 cup (90 g - 120 g) maple syrup ((depending on how sweet you want the energy bites to be))",
     "1.8 oz 50 g melted dairy free white chocolate for the drizzle ((optional))"
   ],
-  "instructions": "In a bowl, mix together all the ingredients except the dairy free white chocolate, until everything is evenly distributed and you get a homogeneous mixture, dough-like in consistency.\nRoll ~ 1 - 1 1/2 tbsp of the mixture into balls, put them onto a baking tray and freeze for about 1/2 hour.\nDrizzle with melted dairy free white chocolate and return to the freezer until the chocolate has set. (optional)\nThe matcha no bake energy bites keep well in a closed container in the fridge for about 1 week, and in the freezer for about 3 weeks. If you keep them in the freezer, take them out about 10 - 15 minutes until you start munching.\nEnjoy!",
   "instructions_list": [
     "In a bowl, mix together all the ingredients except the dairy free white chocolate, until everything is evenly distributed and you get a homogeneous mixture, dough-like in consistency.",
     "Roll ~ 1 - 1 1/2 tbsp of the mixture into balls, put them onto a baking tray and freeze for about 1/2 hour.",
diff --git a/tests/test_data/theloopywhisk.com/theloopywhisk_2.json b/tests/test_data/theloopywhisk.com/theloopywhisk_2.json
index c0286872..324f564d 100644
--- a/tests/test_data/theloopywhisk.com/theloopywhisk_2.json
+++ b/tests/test_data/theloopywhisk.com/theloopywhisk_2.json
@@ -53,7 +53,6 @@
       "purpose": "You will also need:"
     }
   ],
-  "instructions": "For blackberry reduction:\nIn a small saucepan, cook the blackberries on medium-high heat until they have released their juices and part of the liquid has evaporated.\nPass the blackberry mixture through a sieve to remove the seeds and skin.\nReturn the blackberry juices to the saucepan and cook them further until thickened. You want them to be viscous, but not quite jam-like.\nRemove from heat and allow to cool completely.\nFor crushed graham cracker crust:\nAdjust the oven rack to the middle position, pre-heat the oven to 355ºF (180ºC) and line an 8 inch square baking tin with baking/greaseproof paper.\nMix together the crushed digestive biscuits and melted butter, then press them into the lined baking tin to form a firm, even layer. This is easiest done using the flat bottom of a glass or measuring cup.Depending on the type and brand of cookies/biscuits you use, you might need slightly less or slightly more butter than listed in this recipe. Add the butter slowly, mixing well after each addition, until you reach the consistency of wet sand. You want a mixture that somewhat sticks together or holds its shape when pressed together, but it shouldn't feel/look greasy or oily.\nBake at 355ºF (180ºC) for 10 minutes, then remove from the oven and allow to cool slightly.\nFor base cheesecake filling:\nReduce the oven temperature to 285ºF (140ºC).\nIn a large bowl using a whisk, mix the cream cheese and yoghurt together until smooth. Make sure to MIX rather than whisk or aerate – you don't want to incorporate too much air into the mixture. If you don't want to do this by hand, don't use a hand mixer. Instead, use a stand mixer fitted with the paddle attachment on the lowest speed setting.\nAdd the sugar and cornstarch, and mix until combined.\nAdd the eggs, one at a time, mixing well after each addition, until smooth.\nAdd the lemon juice, vanilla and lemon zest. Mix well until smooth.\nAssembling the blackberry cheesecake bars:\nAdd 1 1/2 tablespoons of the base cheesecake filling into the cooled blackberry reduction and mix until evenly combined. Set aside.\nTransfer the remaining base cheesecake filling on top of the slightly cooled cheesecake crust, and smooth it out into an even layer.\nGently spoon the blackberry mixture on top of the base cheesecake filling (see post for step-by-step photos) and use a skewer or toothpick to swirl it around.\nEvenly distribute the fresh blackberries on top.\nBake at 285ºF (140ºC) for about 30-35 minutes, or until the filling is very light golden brown around the edges and the middle is still slightly wobbly when you shake the baking tin.\nTurn off the oven and allow the cheesecake bars to cool to room temperature in the turned-off oven with the oven door ajar.\nOnce cooled to room temperature, transfer the cheesecake bars into the fridge for at least 1 hour (or preferably overnight) before removing them from the baking tin and serving.\nStorage:\nThe blackberry cheesecake bars keep well in a closed container in the fridge for 3 - 4 days.",
   "instructions_list": [
     "For blackberry reduction:",
     "In a small saucepan, cook the blackberries on medium-high heat until they have released their juices and part of the liquid has evaporated.",
diff --git a/tests/test_data/thepalatablelife.com/thepalatablelife_1.json b/tests/test_data/thepalatablelife.com/thepalatablelife_1.json
index a1b085cb..2cb37b4b 100644
--- a/tests/test_data/thepalatablelife.com/thepalatablelife_1.json
+++ b/tests/test_data/thepalatablelife.com/thepalatablelife_1.json
@@ -24,7 +24,6 @@
   ],
   "category": "Main Course",
   "yields": "40 servings",
-  "description": "",
   "total_time": 25,
   "cook_time": 15,
   "prep_time": 10,
diff --git a/tests/test_data/thepalatablelife.com/thepalatablelife_2.json b/tests/test_data/thepalatablelife.com/thepalatablelife_2.json
index b75ae745..b50c82a9 100644
--- a/tests/test_data/thepalatablelife.com/thepalatablelife_2.json
+++ b/tests/test_data/thepalatablelife.com/thepalatablelife_2.json
@@ -69,6 +69,5 @@
   ],
   "category": "Dessert",
   "yields": "12 servings",
-  "description": "",
   "image": "https://www.thepalatablelife.com/wp-content/uploads/2023/12/peppermint-swirl-cookies-scaled.jpg"
 }