Repository: hhursev/recipe-scrapers

Issue:
V14: using 'scrape_html' for an unsupported website unexpectedly implies 'wild_mode'.
During prep for the V15 migration I'm planning to add a deprecation warning to the `scrape_me` function in V14.  It'll continue to be available and usable while the V14 branch is maintained, although we should help folks become aware that it'll be removed at some point.

The deprecation message should mention `scrape_html` as the migration path -- so I had a quick look at the V14 code for that while writing it, and noticed an unexpected behaviour; if a recipe site isn't found in our `SCRAPERS` dictionary, we automatically attempt `wild_mode` scraping.  I think that should probably be considered a bug (`wild_mode` is generally opt-in).

Discussion:

Patch:
diff --git a/recipe_scrapers/__init__.py b/recipe_scrapers/__init__.py
index f484e803..d48dbebb 100644
--- a/recipe_scrapers/__init__.py
+++ b/recipe_scrapers/__init__.py
@@ -822,6 +822,10 @@ def scrape_html(
             scraper = SCRAPERS[host_name]
 
     if not scraper:
+        if not options.get("wild_mode", False):
+            raise WebsiteNotImplementedError(host_name)
+
+        options.pop("wild_mode")
         wild_scraper = SchemaScraperFactory.generate(url=org_url, html=html, **options)
 
         if not wild_scraper.schema.data:


Test patch:
diff --git a/tests/__init__.py b/tests/__init__.py
index d41434a6..e7d9a7ba 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -3,7 +3,7 @@ import pathlib
 import unittest
 from typing import Callable
 
-from recipe_scrapers import scrape_html
+from recipe_scrapers import SCRAPERS, scrape_html
 from recipe_scrapers._exceptions import StaticValueException
 from recipe_scrapers._grouping_utils import IngredientGroup
 
@@ -42,6 +42,7 @@ OPTIONAL_TESTS = [
 
 class RecipeTestCase(unittest.TestCase):
     maxDiff = None
+    been_wild = False
 
 
 def test_func_factory(
@@ -82,7 +83,12 @@ def test_func_factory(
                 IngredientGroup(**group)
                 for group in expect.get("ingredient_groups", [])
             ]
-        actual = scrape_html(testhtml.read_text(encoding="utf-8"), host)
+
+        kwargs = {"wild_mode": True} if host not in SCRAPERS else {}
+        actual = scrape_html(testhtml.read_text(encoding="utf-8"), host, **kwargs)
+        if kwargs.get("wild_mode"):
+            self.assertFalse(self.been_wild, "Only one wild mode test should occur.")
+            type(self).been_wild = True
 
         # Mandatory tests
         # If the key isn't present, check an assertion is raised
diff --git a/tests/library/test_exceptions.py b/tests/library/test_exceptions.py
index e35d5634..2b395f09 100644
--- a/tests/library/test_exceptions.py
+++ b/tests/library/test_exceptions.py
@@ -3,15 +3,20 @@ import unittest
 from recipe_scrapers import (
     NoSchemaFoundInWildMode,
     WebsiteNotImplementedError,
+    scrape_html,
     scrape_me,
 )
 
 
 class TestExceptions(unittest.TestCase):
-    def test_website_not_implemented_error(self):
+    def test_website_not_implemented_error_legacy(self):
         with self.assertRaises(WebsiteNotImplementedError):
             scrape_me("https://example.com/recipe")
 
+    def test_website_not_implemented_error(self):
+        with self.assertRaises(WebsiteNotImplementedError):
+            scrape_html(html="<html></html>", org_url="http://example.com/recipe")
+
     def test_no_schema_found_in_wild_mode_error(self):
         exception = NoSchemaFoundInWildMode("example.com")