Crate rust_recipe

Source
Expand description

§rust-recipe

crates.io Documentation CI Status

rust-recipe is a Rust crate that scrapes recipes from websites. It is inspired by the Golang library “go-recipe”.

§Adding to your Project

cargo add rust-recipe

Optionally, you can use the blocking or async features.

§Usage

§Custom Scraping

By default, the crate provides the scrape_recipe method, which takes in HTML you have scraped from the website and attempts to parse it. The RecipeInformationProvider trait provides the methods available to fetch information once scraped.

use rust_recipe::scrape_recipe;
use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let url = "https://www.bbcgoodfood.com/recipes/crab-lasagne";
    let html = ureq::get(url).call()?.into_string()?;
    let recipe = scrape_recipe(&html).unwrap();

    println!("Fetching {:?}...\n", url);
    let desc = recipe.description().unwrap();
    println!("Description: {}", desc);
    println!();
    println!("Ingredients:");
    for i in recipe.ingredients().unwrap().iter() {
        println!("- {}", i);
    }

    Ok(())
}

Custom scrapers can also be used by implementing the RecipeScraper trait.

use rust_recipe::{custom_scrape_recipe, RecipeInformationProvider, RecipeScraper};
use std::{collections::HashMap, error::Error};

fn main() -> Result<(), Box<dyn Error>> {
    let url = "https://www.bbcgoodfood.com/recipes/crab-lasagne";
    let html = ureq::get(url).call()?.into_string()?;
    let scraper = CustomScraper {};
    let recipe = custom_scrape_recipe(&html, scraper).unwrap();

    println!("Fetching {:?}...\n", url);
    let desc = recipe.description().unwrap();
    println!("Description: {}", desc);
    println!();
    println!("Ingredients:");
    for i in recipe.ingredients().unwrap().iter() {
        println!("- {}", i);
    }

    Ok(())
}

pub struct CustomScraper {...}

pub struct CustomRecipeInfoProvider {
    vals: HashMap<String, String>,
}

impl RecipeScraper for CustomScraper {
    fn scrape_recipe(
        self,
        html: &str,
    ) -> Result<Box<dyn rust_recipe::RecipeInformationProvider>, serde_json::Error> {
        let mut m = HashMap::new();
        m.insert(
            String::from("description"),
            String::from("My favourite recipe"),
        );
        m.insert(
            String::from("ingredients"),
            String::from("carrots, potatoes"),
        );
        ...
        Ok(Box::new(CustomRecipeInfoProvider { vals: m }))
    }
}

impl RecipeInformationProvider for CustomRecipeInfoProvider {
    ...
    fn description(&self) -> Option<String> {
        self.vals.get("description").cloned()
    }

    fn ingredients(&self) -> Option<Vec<String>> {
        self.vals
            .get("ingredients")
            .cloned()
            .map(|s| s.split(", ").map(String::from).collect())
    }
    ...
}

§Async

The async feature uses the reqwest to make an async call to the URL provided:

use rust_recipe::scrape_recipe_from_url;

#[tokio::main]
async fn main() {
    let url = "https://www.bbcgoodfood.com/recipes/crab-lasagne";
    println!("Fetching {:?}...\n", url);
    let recipe = scrape_recipe_from_url(url).await.unwrap();

    let desc = recipe.description().unwrap();
    println!("Description: {}", desc);
    println!();
    println!("Ingredients:");
    for i in recipe.ingredients().unwrap().iter() {
        println!("- {}", i);
    }
}

§Blocking

The blocking feature uses the ureq crate to make a blocking call to the URL provided.

use rust_recipe::{scrape_recipe_from_url_blocking, RecipeScraper};

fn main() {
    let url = "https://www.bbcgoodfood.com/recipes/crab-lasagne";
    println!("Fetching {:?}...\n", url);
    let recipe = scrape_recipe_from_url_blocking(url).unwrap();

    let desc = recipe.description().unwrap();
    println!("Description: {}", desc);
    println!();
    println!("Ingredients:");
    for i in recipe.ingredients().unwrap().iter() {
        println!("- {}", i);
    }
}

Modules§

nutrition_information
recipe_information_provider
restricted_diet

Structs§

NutritionInformation
Nutritional Information from a recipe. See https://schema.org/NutritionInformation

Enums§

RestrictedDiet
The type of dietary restrictions that a recipe caters for. See https://schema.org/RestrictedDiet

Traits§

RecipeInformationProvider
Provides methods to retrieve information from a recipe after it has been scraped. See https://schema.org/Recipe
RecipeScraper
Provides methods to scrape HTML for recipe information.

Functions§

custom_scrape_recipe
Uses a custom scraper to retrieve a recipe
scrape_recipe
Takes some HTML and attempts to parse a recipe to a RecipeInformationProvider