Skip to content

Commit

Permalink
Merge branch 'main' into v14
Browse files Browse the repository at this point in the history
Conflicts:
	README.rst
	recipe_scrapers/__init__.py
	recipe_scrapers/__version__.py
  • Loading branch information
jayaddison committed Oct 20, 2024
2 parents bbb7e2d + bc8cb72 commit 2d8875b
Show file tree
Hide file tree
Showing 123 changed files with 71,175 additions and 5,639 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-13, windows-latest]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13.0-rc.3"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
include:
# set toxenv to workaround-darwin on macos (check tox.ini)
- toxenv: py
Expand Down
15 changes: 14 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Scrapers available for:
- `https://101cookbooks.com/ <https://101cookbooks.com/>`_
- `https://15gram.be <https://15gram.be>`_
- `https://www.750g.com <https://www.750g.com>`_
- `https://abeautifulmess.com/ <https://abeautifulmess.com/>`_
- `https://aberlehome.com/ <https://aberlehome.com>`_
- `https://abuelascounter.com/ <https://abuelascounter.com>`_
- `https://www.acouplecooks.com <https://acouplecooks.com/>`_
Expand Down Expand Up @@ -107,14 +108,18 @@ Scrapers available for:
- `https://bakingmischief.com/ <https://bakingmischief.com/>`_
- `https://barefeetinthekitchen.com/ <https://barefeetinthekitchen.com/>`_
- `https://barefootcontessa.com/ <https://barefootcontessa.com>`_
- `https://barefootinthepines.com/ <https://barefootinthepines.com/>`_
- `https://bbc.com/ <https://bbc.com/food/recipes>`_
- `.co.uk <https://bbc.co.uk/food/recipes>`__
- `https://bbcgoodfood.com/ <https://bbcgoodfood.com>`_
- `https://bestrecipes.com.au/ <https://bestrecipes.com.au>`_
- `https://betterfoodguru.com/ <https://betterfoodguru.com/>`_
- `https://bettybossi.ch/ <https://bettybossi.ch>`_
- `https://bettycrocker.com/ <https://bettycrocker.com>`_
- `https://beyondfrosting.com/ <https://beyondfrosting.com/>`_
- `https://biancazapatka.com/ <https://biancazapatka.com>`_
- `https://bigoven.com/ <https://bigoven.com>`_
- `https://bitsofcarey.com/ <https://bitsofcarey.com/>`_
- `https://blueapron.com/ <https://blueapron.com>`_
- `https://bluejeanchef.com/ <https://bluejeanchef.com/>`_
- `https://www.bodybuilding.com/ <https://www.bodybuilding.com/>`_
Expand All @@ -124,8 +129,11 @@ Scrapers available for:
- `https://bowlofdelicious.com/ <https://bowlofdelicious.com/>`_
- `https://breadtopia.com/ <https://breadtopia.com/>`_
- `https://briceletbaklava.ch/ <https://briceletbaklava.ch/>`_
- `https://brokenovenbaking.com/ <https://brokenovenbaking.com/>`_
- `https://budgetbytes.com/ <https://budgetbytes.com>`_
- `https://cafedelites.com/ <https://cafedelites.com/>`_
- `https://cakemehometonight.com/ <https://cakemehometonight.com/>`_
- `https://cambreabakes.com/ <https://cambreabakes.com/>`_
- `https://carlsbadcravings.com/ <https://carlsbadcravings.com/>`_
- `https://castironketo.net/ <https://castironketo.net/>`_
- `https://cdkitchen.com/ <https://cdkitchen.com/>`_
Expand All @@ -135,15 +143,18 @@ Scrapers available for:
- `https://chefsavvy.com/ <https://chefsavvy.com/>`_
- `https://claudia.abril.com.br/ <https://claudia.abril.com.br>`_
- `https://closetcooking.com/ <https://closetcooking.com>`_
- `https://colleenchristensennutrition.com/ <https://colleenchristensennutrition.com/>`_
- `https://comidinhasdochef.com/ <https://comidinhasdochef.com/>`_
- `https://cook-talk.com/ <https://cook-talk.com/>`_
- `https://cookeatshare.com/ <https://cookeatshare.com/>`_
- `https://cookieandkate.com/ <https://cookieandkate.com/>`_
- `https://cookiesandcups.com/ <https://cookiesandcups.com/>`_
- `https://cooking.nytimes.com/ <https://cooking.nytimes.com>`_
- `https://cookingcircle.com/ <https://cookingcircle.com/>`_
- `https://cookinglight.com/ <https://cookinglight.com/>`_
- `https://cookpad.com/ <https://cookpad.com/>`_
- `https://www.coop.se/ <https://www.coop.se/>`_
- `https://cookwell.com/ <https://cookwell.com/>`_
- `https://copykat.com/ <https://copykat.com>`_
- `https://www.costco.com/ <https://www.costco.com>`_
- `https://countryliving.com/ <https://countryliving.com>`_
Expand Down Expand Up @@ -221,6 +232,7 @@ Scrapers available for:
- `https://www.hersheyland.com/ <https://www.hersheyland.com/>`_
- `https://www.homechef.com/ <https://www.homechef.com/>`_
- `https://hostthetoast.com/ <https://hostthetoast.com/>`_
- `https://hungryhappens.net/ <https://hungryhappens.net/>`_
- `https://www.ica.se/ <https://www.ica.se/>`_
- `https://www.im-worthy.com/ <https://www.im-worthy.com>`_
- `https://inbloombakery.com/ <https://inbloombakery.com/>`_
Expand Down Expand Up @@ -378,6 +390,7 @@ Scrapers available for:
- `https://sobors.hu/ <https://sobors.hu>`_
- `https://www.southerncastiron.com/ <https://www.southerncastiron.com>`_
- `https://southernliving.com/ <https://southernliving.com/>`_
- `https://spainonafork.com/ <https://spainonafork.com/>`_
- `https://spendwithpennies.com/ <https://spendwithpennies.com/>`_
- `https://www.springlane.de <https://www.springlane.de>`_
- `https://www.staysnatched.com/ <https://www.staysnatched.com/>`_
Expand All @@ -399,7 +412,7 @@ Scrapers available for:
- `https://theclevercarrot.com/ <https://theclevercarrot.com>`_
- `https://www.thecookierookie.com/ <https://www.thecookierookie.com/>`_
- `https://thecookingguy.com/ <https://thecookingguy.com>`_
- `https://theexpertguides.com/ <https://theexpertguides.com>`_
- `https://thefoodietakesflight.com/ <https://thefoodietakesflight.com/>`_
- `https://theglutenfreeaustrian.com/ <https://theglutenfreeaustrian.com/>`_
- `https://thehappyfoodie.co.uk/ <https://thehappyfoodie.co.uk>`_
- `https://thekitchencommunity.org/ <https://thekitchencommunity.org/>`_
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"License :: OSI Approved :: MIT License",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
Expand Down
30 changes: 28 additions & 2 deletions recipe_scrapers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from ._exceptions import NoSchemaFoundInWildMode, WebsiteNotImplementedError
from ._factory import SchemaScraperFactory
from ._utils import get_host_name
from .abeautifulmess import ABeautifulMess
from .aberlehome import AberleHome
from .abril import Abril
from .abuelascounter import AbuelasCounter
Expand Down Expand Up @@ -37,13 +38,17 @@
from .bakingsense import BakingSense
from .barefeetinthekitchen import BarefeetInTheKitchen
from .barefootcontessa import BareFootContessa
from .barefootinthepines import BarefootInThePines
from .bbcfood import BBCFood
from .bbcgoodfood import BBCGoodFood
from .bestrecipes import BestRecipes
from .betterfoodguru import BetterFoodGuru
from .bettybossi import BettyBossi
from .bettycrocker import BettyCrocker
from .beyondfrosting import BeyondFrosting
from .biancazapatka import BiancaZapatka
from .bigoven import BigOven
from .bitsofcarey import BitsOfCarey
from .blueapron import BlueApron
from .bluejeanchef import BlueJeanChef
from .bodybuilding import Bodybuilding
Expand All @@ -52,8 +57,11 @@
from .bowlofdelicious import BowlOfDelicious
from .breadtopia import Breadtopia
from .briceletbaklava import BricelEtBaklava
from .brokenovenbaking import BrokenOvenBaking
from .budgetbytes import BudgetBytes
from .cafedelites import CafeDelites
from .cakemehometonight import CakeMeHomeTonight
from .cambreabakes import CambreaBakes
from .carlsbadcravings import CarlsBadCravings
from .castironketo import CastIronKeto
from .cdkitchen import CdKitchen
Expand All @@ -62,14 +70,17 @@
from .chefnini import Chefnini
from .chefsavvy import ChefSavvy
from .closetcooking import ClosetCooking
from .colleenchristensennutrition import ColleenChristensenNutrition
from .comidinhasdochef import ComidinhasDoChef
from .cookeatshare import CookEatShare
from .cookieandkate import CookieAndKate
from .cookiesandcups import CookiesAndCups
from .cookingcircle import CookingCircle
from .cookinglight import CookingLight
from .cookpad import CookPad
from .cooktalk import CookTalk
from .coopse import CoopSE
from .cookwell import CookWell
from .copykat import CopyKat
from .costco import Costco
from .countryliving import CountryLiving
Expand Down Expand Up @@ -147,6 +158,7 @@
from .hersheyland import HersheyLand
from .homechef import HomeChef
from .hostthetoast import Hostthetoast
from .hungryhappens import HungryHappens
from .ica import Ica
from .ig import IG
from .imworthy import ImWorthy
Expand Down Expand Up @@ -301,6 +313,7 @@
from .sobors import SoBors
from .southerncastiron import SouthernCastIron
from .southernliving import SouthernLiving
from .spainonafork import SpainOnAFork
from .spendwithpennies import SpendWithPennies
from .springlane import Springlane
from .staysnatched import StaySnatched
Expand All @@ -322,7 +335,7 @@
from .theclevercarrot import TheCleverCarrot
from .thecookierookie import TheCookieRookie
from .thecookingguy import TheCookingGuy
from .theexpertguides import TheExpertGuides
from .thefoodietakesflight import TheFoodieTakesFlight
from .theglutenfreeaustrian import TheGlutenFreeAustrian
from .thehappyfoodie import TheHappyFoodie
from .thekitchencommunity import TheKitchenCommunity
Expand Down Expand Up @@ -376,6 +389,7 @@
from .zenbelly import ZenBelly

SCRAPERS = {
ABeautifulMess.host(): ABeautifulMess,
ACoupleCooks.host(): ACoupleCooks,
AFlavorJournal.host(): AFlavorJournal,
ALittleBitYummy.host(): ALittleBitYummy,
Expand Down Expand Up @@ -408,11 +422,15 @@
BakingMischief.host(): BakingMischief,
BareFootContessa.host(): BareFootContessa,
BarefeetInTheKitchen.host(): BarefeetInTheKitchen,
BarefootInThePines.host(): BarefootInThePines,
BestRecipes.host(): BestRecipes,
BetterFoodGuru.host(): BetterFoodGuru,
BettyBossi.host(): BettyBossi,
BettyCrocker.host(): BettyCrocker,
BeyondFrosting.host(): BeyondFrosting,
BiancaZapatka.host(): BiancaZapatka,
BigOven.host(): BigOven,
BitsOfCarey.host(): BitsOfCarey,
BlueApron.host(): BlueApron,
BlueJeanChef.host(): BlueJeanChef,
Bodybuilding.host(): Bodybuilding,
Expand All @@ -421,8 +439,11 @@
BongEats.host(): BongEats,
Breadtopia.host(): Breadtopia,
BricelEtBaklava.host(): BricelEtBaklava,
BrokenOvenBaking.host(): BrokenOvenBaking,
BudgetBytes.host(): BudgetBytes,
CafeDelites.host(): CafeDelites,
CakeMeHomeTonight.host(): CakeMeHomeTonight,
CambreaBakes.host(): CambreaBakes,
CarlsBadCravings.host(): CarlsBadCravings,
CastIronKeto.host(): CastIronKeto,
CdKitchen.host(): CdKitchen,
Expand All @@ -431,11 +452,14 @@
Chefkoch.host(): Chefkoch,
Chefnini.host(): Chefnini,
ClosetCooking.host(): ClosetCooking,
ColleenChristensenNutrition.host(): ColleenChristensenNutrition,
ComidinhasDoChef.host(): ComidinhasDoChef,
CookEatShare.host(): CookEatShare,
CookPad.host(): CookPad,
CookTalk.host(): CookTalk,
CookWell.host(): CookWell,
CookieAndKate.host(): CookieAndKate,
CookiesAndCups.host(): CookiesAndCups,
CookingCircle.host(): CookingCircle,
CookingLight.host(): CookingLight,
CoopSE.host(): CoopSE,
Expand Down Expand Up @@ -465,6 +489,7 @@
GourmetTraveller.host(): GourmetTraveller,
GrandFrais.host(): GrandFrais,
HeatherChristo.host(): HeatherChristo,
HungryHappens.host(): HungryHappens,
InBloomBakery.host(): InBloomBakery,
InGoodFlavor.host(): InGoodFlavor,
JoCooks.host(): JoCooks,
Expand Down Expand Up @@ -499,10 +524,12 @@
RicettePerBimby.host(): RicettePerBimby,
SandwhichTribunal.host(): SandwhichTribunal,
SavoryNothings.host(): SavoryNothings,
SpainOnAFork.host(): SpainOnAFork,
StrongrFastr.host(): StrongrFastr,
TasteAtlas.host(): TasteAtlas,
TheCookieRookie.host(): TheCookieRookie,
TheCookingGuy.host(): TheCookingGuy,
TheFoodieTakesFlight.host(): TheFoodieTakesFlight,
TheGlutenFreeAustrian.host(): TheGlutenFreeAustrian,
TheLoopyWhisk.host(): TheLoopyWhisk,
ThePalatableLife.host(): ThePalatableLife,
Expand Down Expand Up @@ -722,7 +749,6 @@
Tasty.host(): Tasty,
TastyKitchen.host(): TastyKitchen,
TheCleverCarrot.host(): TheCleverCarrot,
TheExpertGuides.host(): TheExpertGuides,
TheHappyFoodie.host(): TheHappyFoodie,
TheKitchenCommunity.host(): TheKitchenCommunity,
TheKitchenMagPie.host(): TheKitchenMagPie,
Expand Down
28 changes: 28 additions & 0 deletions recipe_scrapers/abeautifulmess.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from ._abstract import AbstractScraper
from ._grouping_utils import group_ingredients
from ._utils import get_equipment


class ABeautifulMess(AbstractScraper):
@classmethod
def host(cls):
return "abeautifulmess.com"

def ingredient_groups(self):
return group_ingredients(
self.ingredients(),
self.soup,
".wprm-recipe-ingredient-group h4",
".wprm-recipe-ingredient",
)

def equipment(self):
equipment_container = self.soup.select_one(".wprm-recipe-equipment-container")
if not equipment_container:
return None

equipment_items = [
item.get_text()
for item in equipment_container.select(".wprm-recipe-equipment-name")
]
return get_equipment(equipment_items)
57 changes: 57 additions & 0 deletions recipe_scrapers/barefootinthepines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from ._abstract import AbstractScraper
from ._grouping_utils import group_ingredients


class BarefootInThePines(AbstractScraper):
@classmethod
def host(cls):
return "barefootinthepines.com"

def ingredient_groups(self):
return group_ingredients(
self.ingredients(),
self.soup,
".mv-create-ingredients h4",
".mv-create-ingredients ul li",
)

def nutrients(self):
nutrition_section = self.soup.select_one(".mv-create-nutrition-box")
if not nutrition_section:
return None

raw_nutrition_data = {
item.select_one(".mv-create-nutrition-label")
.get_text(strip=True)
.lower()
.rstrip(":"): item.get_text(strip=True)
.replace(
item.select_one(".mv-create-nutrition-label").get_text(strip=True), ""
)
.strip()
for item in nutrition_section.select(".mv-create-nutrition-item")
if item.select_one(".mv-create-nutrition-label")
}

nutrition_label_mapping = {
"calories": "calories",
"carbohydrates": "carbohydrateContent",
"cholesterol": "cholesterolContent",
"total fat": "fatContent",
"fiber": "fiberContent",
"protein": "proteinContent",
"saturated fat": "saturatedFatContent",
"serving size": "servingSize",
"sodium": "sodiumContent",
"sugar": "sugarContent",
"trans fat": "transFatContent",
"unsaturated fat": "unsaturatedFatContent",
}

standardized_nutrition_data = {
nutrition_label_mapping[custom_label]: value
for custom_label, value in raw_nutrition_data.items()
if custom_label in nutrition_label_mapping
}

return standardized_nutrition_data
16 changes: 16 additions & 0 deletions recipe_scrapers/betterfoodguru.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from ._abstract import AbstractScraper
from ._grouping_utils import group_ingredients


class BetterFoodGuru(AbstractScraper):
@classmethod
def host(cls):
return "betterfoodguru.com"

def ingredient_groups(self):
return group_ingredients(
self.ingredients(),
self.soup,
".wprm-recipe-ingredient-group h4",
".wprm-recipe-ingredient",
)
28 changes: 28 additions & 0 deletions recipe_scrapers/beyondfrosting.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from ._abstract import AbstractScraper
from ._grouping_utils import group_ingredients
from ._utils import get_equipment


class BeyondFrosting(AbstractScraper):
@classmethod
def host(cls):
return "beyondfrosting.com"

def ingredient_groups(self):
return group_ingredients(
self.ingredients(),
self.soup,
".tasty-recipes-ingredients-body p strong",
".tasty-recipes-ingredients-body ul li",
)

def equipment(self):
equipment_items = self.soup.select(
".tasty-recipes-equipment .tasty-link-card a.tasty-link"
)
equipment_list = [
item.find_next("p").get_text(strip=True)
for item in equipment_items
if "affiliate link" not in item.find_next("p").get_text(strip=True).lower()
]
return get_equipment(equipment_list)
Loading

0 comments on commit 2d8875b

Please sign in to comment.