A minimal, working example of a third-party site module for NicheImageRipper, built against the Sdk project (exists from v5.0.0 of NicheImageRipper). Use this as a starting point if you're writing your own parser.
This example targets trendszine.com. This does not show off all the capabilities of a module, but most parsers can be this simple. The Sdk has a lot of extra features for more complex sites, but this is enough to get you started.
- The minimum a parser needs:
IHtmlParser(ParserName,SupportedUrls), a constructor matching the standard(WebDriver, Dictionary<string, string>, FilenameScheme)shape, and an override ofParse. - Basic scraping with
Soupify+ XPath, including lazy-loading images as the page scrolls. - Paginating through a site by clicking a "next page" button and re-souping.
- Returning results via
RipInfo.FromUrlList.
- References
NicheImageRipper.Sdk(via project reference). Custom modules should not reference any other NIR assemblies directly, only the Sdk. - .NET version matching whatever the Sdk targets.
Thsi is a module meant to be loaded by the main app. Build the module, then drop the output folder into the main app's modules/ directory (as its own subfolder) so SiteModuleLoader picks it up at startup. Build with dotnet publish, not just dotnet build — the loader needs the .deps.json alongside the DLL to resolve any dependencies your module brings on its own.
Once loaded, URLs from trendszine.com should route to this parser automatically — no other registration needed.
A few things worth knowing if you're adapting this for a different site:
ParserNameandSupportedUrlsare how the framework finds your parser — keepSupportedUrlsscoped to the exact host(s) you handle.- Stick to the standard 3-parameter constructor shown here. The framework constructs parsers via that exact signature; a different one won't be found.
- If your site needs something beyond a plain parser — login, delegating to another parser for embedded links, time-sensitive/expiring links, a local cache file — there are marker interfaces and base classes in the Sdk for each of those. This example doesn't need any of them, so it doesn't show them, but they're there when you do.
- This was tested against the real framework and confirmed working — if something in your own module doesn't behave the way this one does, the difference is probably in your module, not the Sdk.