Web Image Scraper v0.82
Scrape a whole website's images without leaving ComfyUI
- output_path
- metadata_json_path
- files_found
- files_downloaded
- videos_downloaded
- duplicates_removed
- duplicates_moved
- skipped_small
- skipped_platform
- skipped_not_media
- skipped_already_processed
- failed_download
- screenshots_taken
- stats_summary
Most ComfyUI nodes make images. This one goes and gets them. The Web Image Scraper (class EricWebFileScraper_v082, part of EricRollei's Download Tools pack) points a real headless browser at a URL, walks the page - pagination, infinite scroll, the whole thing - and dumps the full-resolution images and videos into a folder on your disk. If your workflow is missing a dataset, reference set, or just a pile of references for style, this is the node that fills the gap.
ComfyUI's whole pitch is that everything is a node and every step is visible. That works great for sampling and miserable for "I need a hundred reference images." The normal answer is a browser, a download-all extension, and a lot of clicking. This node collapses all of that into a single node you drop at the end of the graph and run once.
How it actually works
Under the hood it's Playwright driving headless Chromium, with the Scrapling library for the anti-bot and page-parse work. The pack ships 25+ site-specific handlers - Instagram, Reddit, Bluesky, Pinterest, DeviantArt, ArtStation, Flickr, Unsplash, plus a purpose-built handler for IPS/Invision forums that even opens spoiler blocks and walks every page of a topic. Anything without a handler falls through to a generic extractor that grabs every image meeting your size thresholds. Every image gets hashed (perceptual hashing by default) so duplicates are caught even when the same photo appears at different URLs, keeping the largest version. It's genuinely clever for a scraper, and it's the kind of node where "the author clearly scraped a lot of sites" is a compliment.
The inputs that matter
You will set maybe five of these. The rest have sane defaults:
url- where to start. Multiline, so you can drop several pages.output_dir- where files land; relative paths resolve against ComfyUI's output folder.min_width/min_height- skip anything smaller than this (512px default). This is how you avoid thumbnail spam.download_images/download_videos/download_audio- pick your media types.max_files- a hard cap (1000 default) so you don't accidentally download a whole forum.
Two worth knowing in the optional tab: use_stealth_mode for sites that fight back, and interaction_sequence, which takes a small JSON list of click / fill / wait_for_selector steps for automating galleries that need a button press. hash_algorithm lets you swap between average_hash, phash, dhash, and whash if dedupe is too aggressive or too loose.
Wiring the outputs
This is an output node - it ends the graph, it doesn't feed a sampler. Its output_path (STRING) and metadata_json_path are the two you'd wire into a text/display node if you want the result logged; the rest are count outputs (files_found, files_downloaded, videos_downloaded, duplicates_removed, skipped_small…) plus a stats_summary string. In practice you read the node's own report and go open the folder.
Installing it
Via ComfyUI Manager, search "Download Tools" and hit install. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/EricRollei/Download_Tools
cd Download_Tools && pip install -r requirements.txt
Here's the gotcha Manager won't save you from: Playwright needs its browser binaries, which pip does not install. Run this once against ComfyUI's Python:
python -m playwright install
Skip that and the node imports fine but can't launch a browser. FFmpeg is optional and only matters if you let it pull video.
Where it bites
- Browser won't launch - you skipped
playwright install. It's the #1 failure mode. - Sites blocking you - turn on
use_stealth_mode, or setauth_config_pathandsave_cookiesfor login-walled content. - Only thumbnails saved - raise
min_width/min_height. - Duplicates piling up - that's perceptual hashing off; try a different
hash_algorithm.
One more thing to know before you build a commercial pipeline on it: the whole pack is dual-licensed, CC BY-NC 4.0 for non-commercial use, and a paid license for commercial use. Check the LICENSE before you ship anything. Scraping is also legally murky territory in general, and site terms vary - use it on content you're allowed to have.
Inputs (49)
| Name | Type | Default | Description |
|---|---|---|---|
| url | STRING | — | |
| output_dir | STRING | web_scraper_output | — |
| min_width | INT | 5120–10000 | — |
| min_height | INT | 5120–10000 | — |
| max_files | INT | 10000–5000 | — |
| download_images | BOOLEAN | true | — |
| download_videos | BOOLEAN | true | — |
| same_domain_only | BOOLEAN | true | — |
| filename_prefix | STRING | WS81_ | — |
| use_direct_playwrightopt | BOOLEAN | true | — |
| continue_last_runopt | BOOLEAN | false | — |
| use_url_as_folderopt | BOOLEAN | true | — |
| move_duplicatesopt | BOOLEAN | false | — |
| hash_algorithmopt | COMBO | 4 options: average_hash, phash, dhash, whash | |
| extract_metadataopt | BOOLEAN | true | — |
| save_metadata_jsonopt | BOOLEAN | true | — |
| crawl_linksopt | BOOLEAN | false | — |
| crawl_depthopt | INT | 11–5 | — |
| max_pagesopt | INT | 501–500 | — |
| crawl_subfoldersopt | BOOLEAN | true | — |
| skip_first_page_downloadopt | BOOLEAN | false | — |
| link_include_patternopt | STRING | — | |
| link_exclude_patternopt | STRING | — | |
| download_audioopt | BOOLEAN | false | — |
| metadata_export_formatopt | COMBO | json | 3 options: json, csv, md |
| timeout_secondsopt | FLOAT | 1005–600 | — |
| handler_timeoutopt | FLOAT | 12010–1200 | — |
| max_api_pagesopt | INT | 31–100 | — |
| wait_for_network_idleopt | BOOLEAN | false | — |
| playwright_wait_msopt | INT | 10000–60000 | — |
| use_stealth_modeopt | BOOLEAN | false | — |
| stealth_mode_levelopt | COMBO | basic | 3 options: basic, enhanced, extreme |
| use_auto_scrollopt | BOOLEAN | true | — |
| max_auto_scrollsopt | INT | 1500–500 | — |
| scroll_down_timesopt | INT | 1500–200 | — |
| scroll_delay_msopt | INT | 100050–5000 | — |
| interaction_sequenceopt | STRING | — | |
| auth_config_pathopt | STRING | — | |
| save_cookiesopt | BOOLEAN | false | — |
| take_screenshotopt | BOOLEAN | false | — |
| screenshot_elementsopt | STRING | — | |
| screenshot_full_pageopt | BOOLEAN | false | — |
| debug_modeopt | BOOLEAN | false | — |
| use_parallelopt | BOOLEAN | true | — |
| max_workersopt | INT | 41–16 | — |
| reuse_sessionsopt | BOOLEAN | true | — |
| session_expiry_hoursopt | FLOAT | 241–720 | — |
| capture_network_streamopt | BOOLEAN | false | — |
| dump_cache_after_runopt | BOOLEAN | false | — |
Outputs (14)
| Name | Type | Description |
|---|---|---|
| output_path | STRING | — |
| metadata_json_path | STRING | — |
| files_found | INT | — |
| files_downloaded | INT | — |
| videos_downloaded | INT | — |
| duplicates_removed | INT | — |
| duplicates_moved | INT | — |
| skipped_small | INT | — |
| skipped_platform | INT | — |
| skipped_not_media | INT | — |
| skipped_already_processed | INT | — |
| failed_download | INT | — |
| screenshots_taken | INT | — |
| stats_summary | STRING | — |