The scraper looked for span.quantity/span.unit/span.name which don't exist. The real HTML uses <strong> for qty, plain <span> for unit, <a class="ingredients-link"> for name, and <small> for extras like "(darált)". Also add referenceId to Mealie ingredients (required field). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Recipe Importer
Docker container for importing recipes from Hungarian websites into Mealie (Tandoor support planned).
Problem: Mealie's built-in URL import cannot parse ingredients and instructions from Hungarian recipe sites like mindmegette.hu — it imports the title and image but shows "Could not detect ingredients / instructions".
Solution: This container provides a web UI that scrapes Hungarian recipe pages with site-specific parsers, lets you review and edit the extracted data, then pushes it to Mealie via its REST API.
Architecture
┌─────────────────────────────────────────────────┐
│ recipe-importer container (:8000) │
│ │
│ Flask + Gunicorn │
│ ├── /settings → Configure Mealie connection │
│ ├── /import → Paste URL, scrape, review │
│ ├── /scrape → AJAX: parse recipe HTML │
│ ├── /send → AJAX: push to Mealie API │
│ └── /health → Health check │
│ │
│ Modules: │
│ ├── app/config.py → JSON config persistence │
│ ├── app/scraper.py → Site-specific parsers │
│ └── app/mealie.py → Mealie REST API client │
└───────────────────┬─────────────────────────────┘
│ HTTP
▼
┌──────────────────┐
│ Mealie instance │
│ POST /api/recipes│
│ PATCH /api/... │
│ PUT /api/.../img │
└──────────────────┘
Supported Sites
| Site | Ingredients | Instructions | Image |
|---|---|---|---|
| mindmegette.hu | Yes | Yes | Yes |
| Other sites | Fallback (schema.org JSON-LD) | Fallback (schema.org JSON-LD) | Yes (og:image) |
Mindmegette.hu Parser
Extracts data from the Angular-rendered HTML:
- Title:
og:titlemeta tag, with| Mindmegette.husuffix stripped - Description:
og:descriptionmeta tag - Image:
og:imagemeta tag - Ingredients:
div.ingredients→div.ingredients-metarows, each containingspan.quantity,span.unit,span.name,span.extra - Instructions:
mindmegette-wysiwyg-box→ol > lielements
Generic Fallback Parser
For unsupported sites, attempts extraction via:
- Schema.org JSON-LD
@type: Recipeblocks (recipeIngredient,recipeInstructions) - OpenGraph meta tags for title, description, image
Mealie API Integration
The importer uses the Mealie REST API:
- POST
/api/recipes— create a stub recipe (returns slug) - PATCH
/api/recipes/{slug}— populate ingredients, instructions, description, orgURL - PUT
/api/recipes/{slug}/image— upload the recipe image
Authentication uses a long-lived API token (Bearer header), created in Mealie at Profile → API Tokens.
Configuration
All settings are persisted to /data/config.json (mounted as a Docker volume).
| Setting | Description |
|---|---|
mealie_url |
Full URL to Mealie instance (e.g. https://mealie.example.com) |
mealie_api_key |
Mealie API token |
Deployment
Docker Compose
services:
recipe-importer:
image: gitea.dooplex.hu/admin/recipe-importer:0.1.0
container_name: recipe-importer
restart: unless-stopped
ports:
- "8011:8000"
volumes:
- recipe-data:/data
environment:
- SECRET_KEY=change-me-in-production
volumes:
recipe-data:
Environment Variables
| Variable | Default | Description |
|---|---|---|
SECRET_KEY |
recipe-importer-dev-key |
Flask session secret |
DATA_DIR |
/data |
Persistent storage path |
VERSION |
dev |
Shown in the UI navbar |
Building
On the build server (kisfenyo@192.168.0.180):
cd ~/build/recipe-importer
./build.sh X.X.X --push
Web UI
The UI is in Hungarian and uses a dark theme. The workflow is:
- Settings (
/settings) — Enter Mealie URL and API key, test connection - Import (
/import) — Paste a recipe URL, click "Beolvasás" (Scrape) - Review — Edit the title, description, ingredients, instructions in the preview
- Send — Click "Importálás Mealie-be" to push to Mealie
Tech Stack
- Runtime: Python 3.12 (slim)
- Web framework: Flask 3.1 + Gunicorn
- HTML parsing: BeautifulSoup 4 + lxml
- HTTP client: requests
- Container: ~60 MB image