Coverage for cookbook/helper/scrapers/cooksillustrated.py: 82%
38 statements
« prev ^ index » next coverage.py v7.4.0, created at 2023-12-29 01:02 +0100
« prev ^ index » next coverage.py v7.4.0, created at 2023-12-29 01:02 +0100
1import json
2from recipe_scrapers._abstract import AbstractScraper
5class CooksIllustrated(AbstractScraper):
6 @classmethod
7 def host(cls, site='cooksillustrated'):
8 return {
9 'cooksillustrated': f"{site}.com",
10 'americastestkitchen': f"{site}.com",
11 'cookscountry': f"{site}.com",
12 }.get(site)
14 def title(self):
15 return self.schema.title()
17 def image(self):
18 return self.schema.image()
20 def total_time(self):
21 if not self.recipe:
22 self.get_recipe()
23 return self.recipe['recipeTimeNote']
25 def yields(self):
26 if not self.recipe:
27 self.get_recipe()
28 return self.recipe['yields']
30 def ingredients(self):
31 if not self.recipe:
32 self.get_recipe()
33 ingredients = []
34 for group in self.recipe['ingredientGroups']:
35 ingredients += group['fields']['recipeIngredientItems']
36 return [
37 "{} {} {}{}".format(
38 i['fields']['qty'] or '',
39 i['fields']['measurement'] or '',
40 i['fields']['ingredient']['fields']['title'] or '',
41 i['fields']['postText'] or ''
42 )
43 for i in ingredients
44 ]
46 def instructions(self):
47 if not self.recipe:
48 self.get_recipe()
49 if self.recipe.get('headnote', False):
50 i = ['Note: ' + self.recipe.get('headnote', '')]
51 else:
52 i = []
53 return "\n".join(
54 i
55 + [self.recipe.get('whyThisWorks', '')]
56 + [
57 instruction['fields']['content']
58 for instruction in self.recipe['instructions']
59 ]
60 )
62 def nutrients(self):
63 raise NotImplementedError("This should be implemented.")
65 def get_recipe(self):
66 j = json.loads(self.soup.find(type='application/json').string)
67 name = list(j['props']['initialState']['content']['documents'])[0]
68 self.recipe = j['props']['initialState']['content']['documents'][name]