Sometimes you will have to write custom extraction code. This is possible by overriding the CompleteExtraction method of the Entity base type.
[Extraction(DetailsLevel.D)]
public WebImage;

protected override void CompleteExtraction(HtmlNode node, DetailsLevel detailsLevel, DeferredLoadingToken defer)
{
    if (detailsLevel == DetailsLevel.D)
    {
        string value = WebExtensionMethods.GetValue(node, "#bigwall script", null, "B\\('(.*?)'\\)");
        this.FullImage = new WebImage(ExtensionMethods.AsUri(Utils.DecodeBase64(value), false));
    }
}
The HTML node retrieval is still managed by Shaman. If you want full control over the data retrieval, you can override RetrieveDetailsAsync instead:
[Extraction(DetailsLevel.D)]
public string FirstName;

[Extraction(DetailsLevel.D)]
public string LastName;


[RetrieveDetailsMethodInfo(DetailsLevel.D)]
protected override async Task RetrieveDetailsAsync(DetailsLevel detailsLevel, DeferredLoadingToken defer)
{
    if (detailsLevel == DetailsLevel.D)
    {
        var page = await UrlUtils.FormatEscaped("http://www.example.com/{0}", this.Id).GetHtmlNodeAsync();
        this.FirstName = page.GetValue(".firstName");
        this.LastName = page.GetValue(".lastName");
    }
    else
    {
        throw new NotSupportedException();
    }
}
The same RetrieveDetailsAsync override can also provide details for multiple DetailsLevels. The DeferredLoadingToken parameter should be passed to the called methods (when supported) in order to optimize the database access.