11from ._abstract import AbstractScraper
2- from ._utils import get_minutes , get_yields , normalize_string
2+ from ._utils import get_equipment , get_minutes , get_yields , normalize_string
33
44
55class FitMenCook (AbstractScraper ):
@@ -15,21 +15,116 @@ def total_time(self):
1515 return get_minutes (time_text .text .strip ())
1616
1717 def yields (self ):
18- yields = None
18+ if div := self .soup .find ("div" , class_ = "fmc_nos" ):
19+ if span := div .find ("span" ):
20+ return get_yields (f"{ span .get_text (strip = True )} servings" )
21+
1922 for h4 in self .soup .find_all ("h4" ):
20- raw_yield = h4 .text
23+ raw_yield = h4 .get_text ( strip = True )
2124 for word in raw_yield .split ():
2225 if word .isdigit ():
23- yields = word
24-
25- if yields :
26- return get_yields (f"{ yields } servings" )
26+ return get_yields (f"{ word } servings" )
2727
2828 def ingredients (self ):
29- ingredients_parent = self .soup .find ("div" , {"class" : "fmc_ingredients" })
30- ingredients = ingredients_parent .find_all ("li" )
31- return [
32- normalize_string (ingredient .get_text ())
33- for ingredient in ingredients
34- if ingredient .find ("strong" ) is None
29+ parent = self .soup .find ("div" , {"class" : "fmc_ingredients" })
30+ if parent :
31+ return [
32+ normalize_string (li .get_text ())
33+ for li in parent .find_all ("li" )
34+ if not li .find ("strong" ) and normalize_string (li .get_text ())
35+ ]
36+
37+ ingredients = []
38+ seen = set ()
39+ for ul in self .soup .find_all ("ul" , class_ = "fmc_instacart_list" ):
40+ for li in ul .find_all ("li" , recursive = False ):
41+ for junk in li .select ("button, .fmc_btn_container, .product_price" ):
42+ junk .decompose ()
43+ text = normalize_string (li .get_text ())
44+ if text and len (text ) > 2 and text not in seen :
45+ ingredients .append (text )
46+ seen .add (text )
47+ if ingredients :
48+ return ingredients
49+
50+ return []
51+
52+ def nutrients (self ):
53+ data = {}
54+ div = self .soup .find ("div" , class_ = "fmc_macros" )
55+ if not div :
56+ return {}
57+
58+ mapping = {
59+ "Calories" : "calories" ,
60+ "Cal" : "calories" ,
61+ "Protein" : "proteinContent" ,
62+ "Fats" : "fatContent" ,
63+ "Fat" : "fatContent" ,
64+ "Carbs" : "carbohydrateContent" ,
65+ "Carbohydrates" : "carbohydrateContent" ,
66+ "Fiber" : "fiberContent" ,
67+ "Sodium" : "sodiumContent" ,
68+ "Sugar" : "sugarContent" ,
69+ }
70+
71+ for item in div .find_all ("div" , class_ = "fmc_macro" ):
72+ span = item .find ("span" )
73+ if not span :
74+ continue
75+
76+ raw_val = span .get_text (strip = True )
77+ raw_val = raw_val .strip ()
78+ num_value = ""
79+ unit = ""
80+ i = 0
81+ while i < len (raw_val ) and (raw_val [i ].isdigit () or raw_val [i ] == "." ):
82+ num_value += raw_val [i ]
83+ i += 1
84+ if i < len (raw_val ):
85+ unit = raw_val [i :].strip ()
86+ if not num_value :
87+ num_value , unit = raw_val , ""
88+
89+ label = item .get_text (strip = True ).replace (raw_val , "" ).strip ()
90+
91+ for key , field in mapping .items ():
92+ if key in label :
93+ if field == "calories" :
94+ data [field ] = num_value
95+ else :
96+ val = f"{ num_value } { unit } " .strip ()
97+ data [field ] = val if val != num_value else num_value
98+ break
99+ return data
100+
101+ def category (self ):
102+ div = self .soup .find ("div" , class_ = "fmc_grid_cat" )
103+ if not div :
104+ return ""
105+ categories = [
106+ a .get_text (strip = True ) for a in div .find_all ("a" ) if a .get_text (strip = True )
35107 ]
108+ return ", " .join (get_equipment (categories ))
109+
110+ def instructions (self ):
111+ steps = []
112+
113+ rc_steps = self .soup .find ("div" , class_ = "rc_steps" )
114+ if rc_steps :
115+ for li in rc_steps .find_all ("li" , class_ = "rc_step" ):
116+ text = li .get_text (separator = " " , strip = True )
117+ if text :
118+ steps .append (" " .join (text .split ()))
119+
120+ if not steps :
121+ container = self .soup .find ("div" , class_ = "fmc_recipe_the_content" )
122+ if container :
123+ for step_div in container .find_all ("div" , class_ = "fmc_step_wrap" ):
124+ content_div = step_div .find ("div" , class_ = "fmc_step_content" )
125+ if content_div :
126+ text = content_div .get_text (separator = " " , strip = True )
127+ if text :
128+ steps .append (" " .join (text .split ()))
129+
130+ return "\n " .join (steps )
0 commit comments