Skip to content

Commit 5056aef

Browse files
authored
Fitmencook fix (#1834)
* rename existing test * 2 & 3 test cases * yields & new html for original test * nutrients * category * category fix * ingredient fix * instructions
1 parent b661177 commit 5056aef

8 files changed

Lines changed: 10904 additions & 938 deletions

File tree

recipe_scrapers/fitmencook.py

Lines changed: 108 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from ._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

55
class 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

Comments
 (0)