UNPKG

sitemap-xml-parser

Version:

Parses sitemap XML files and returns all listed URLs. CLI and library. Supports TSV/JSON output, filtering, sitemap index files, and gzip compression.

174 lines (126 loc) 7.91 kB
# sitemap-xml-parser Parses sitemap XML files and returns all listed URLs. Can be used as a CLI tool or a Node.js library. - Follows sitemap index files recursively and decompresses gzip automatically - Supports custom request headers, concurrency control, and request timeouts - **CLI:** outputs plain URLs, TSV, or JSON with configurable field selection (`--fields`) - **CLI:** filters URLs by substring or regular expression ## Installation ``` npm install sitemap-xml-parser ``` ## CLI Run without installing via `npx`: ```sh npx sitemap-xml-parser <url> [options] ``` Or, after installing globally (`npm install -g sitemap-xml-parser`): ```sh sitemap-xml-parser <url> [options] ``` Fetched URLs are printed to stdout, one per line. Errors are printed to stderr. See [Options](#options) for available flags. ## Examples ```sh # Print all URLs npx sitemap-xml-parser https://example.com/sitemap.xml # Save URLs to a file, errors to a log npx sitemap-xml-parser https://example.com/sitemap.xml > urls.txt 2> errors.log # Count URLs npx sitemap-xml-parser https://example.com/sitemap.xml --count # Stop after 100 entries npx sitemap-xml-parser https://example.com/sitemap.xml --cap 100 # Filter and count npx sitemap-xml-parser https://example.com/sitemap.xml --filter "blog" --count # Filter by regular expression npx sitemap-xml-parser https://example.com/sitemap.xml --filter-regex "blog/[0-9]{4}/" # Output as TSV (loc, lastmod, changefreq, priority) npx sitemap-xml-parser https://example.com/sitemap.xml --format tsv ``` <details> <summary>CLI: getting more fields — discovering what's available and outputting all of them</summary> Some sitemaps include extension fields such as `image:image` or `news:news` beyond the standard four. If you need to include those fields in your output, use `--list-fields` to find out what's available first. ```sh # Output as JSON with all fields (all fields present in the source XML are included by default) npx sitemap-xml-parser https://example.com/sitemap.xml --format json # Discover all fields present in a sitemap npx sitemap-xml-parser https://example.com/sitemap.xml --list-fields # Output as TSV with custom columns (e.g. image sitemap extension) npx sitemap-xml-parser https://example.com/sitemap.xml --format tsv --fields loc,image:image # Output as TSV with all fields (fetches twice: once to discover fields, once to output) npx sitemap-xml-parser https://example.com/sitemap.xml --format tsv \ --fields "$(npx sitemap-xml-parser https://example.com/sitemap.xml --list-fields | paste -sd, -)" ``` </details> ## Options ### CLI | Flag | Default | Description | |-------------------------|---------|-----------------------------------------------------------------------------| | `--delay <ms>` | `1000` | Milliseconds to wait between batches when following a sitemap index. `--limit` URLs are fetched in parallel per batch; after each batch completes, the process waits `--delay` ms before starting the next. Set to `0` to disable. | | `--limit <n>` | `10` | Number of child sitemaps to fetch concurrently per batch. | | `--timeout <ms>` | `30000` | Milliseconds before a request is aborted. | | `--cap <n>` | — | Stop collecting after this many URL entries. Useful for sampling large sitemaps. | | `--header <Name: Value>`| — | Add a request header. Repeatable. Single: `--header "User-Agent: MyBot/1.0"`. Multiple: `--header "User-Agent: MyBot/1.0" --header "Authorization: Bearer token"` | | `--filter <str>` | — | Only output URLs whose `loc` contains the given string (substring match). Can be combined with `--count` or `--format`. | | `--filter-regex <regex>`| — | Only output URLs whose `loc` matches the given regular expression. Invalid patterns exit non-zero. Can be combined with `--count` or `--format`. | | `--format <fmt>` | — | Output format: `tsv` prints a header row followed by one tab-separated row per entry; `json` outputs a JSON array of entry objects including all fields from the source XML. | | `--fields <f1,f2,...>` | — | Comma-separated list of fields to include in the output. Requires `--format`. For `tsv`, defaults to `loc,lastmod,changefreq,priority`. For `json`, defaults to all fields. Nested values are serialized as JSON in TSV output. | | `--list-fields` | — | Print all field names found across every entry, one per line. Scans the entire sitemap and outputs the union of all keys seen. Useful for discovering available fields before using `--fields`. Compatible with `--filter` and `--filter-regex`. Cannot be combined with `--format`, `--fields`, `--cap`, or `--count`. | | `--count` | — | Print only the total number of URLs. | ### Library | Option | Type | Default | Description | |-----------|------------|---------|------------------------------------| | `delay` | `number` | `1000` | Same as `--delay`. | | `limit` | `number` | `10` | Same as `--limit`. | | `timeout` | `number` | `30000` | Same as `--timeout`. | | `cap` | `number` | — | Same as `--cap`. | | `headers` | `object` | — | Key-value map of request headers. Same as repeated `--header`. | | `onError` | `function` | — | Called as `onError(url, error)` when a fetch or parse fails. The entry is skipped regardless. | | `onEntry` | `function` | — | Called as `onEntry(entry)` each time a URL entry is parsed. `entry` has the same shape as the objects returned by `fetch()`. | ## Features - Follows Sitemap Index files recursively, including nested indexes (Index within an Index) - Automatically decompresses gzip: supports both `.gz` URLs and `Content-Encoding: gzip` responses - Batch processing: fetches `limit` child sitemaps in parallel per batch, then waits `delay` ms after each batch completes - Automatically follows redirects (301/302/303/307/308) up to 5 hops; errors beyond that are reported via `onError`. Custom request headers are forwarded only when the redirect stays on the same origin (same scheme, host, and port); they are stripped on cross-origin redirects. ## Usage ```js const SitemapXMLParser = require('sitemap-xml-parser'); const parser = new SitemapXMLParser('https://example.com/sitemap.xml'); (async () => { const urls = await parser.fetch(); urls.forEach(entry => { console.log(entry.loc); }); })(); ``` ### Custom headers ```js const parser = new SitemapXMLParser('https://example.com/sitemap.xml', { headers: { 'User-Agent': 'MyBot/2.0', 'Authorization': 'Bearer my-token', }, }); ``` ### Error handling with `onError` Failed URLs (network errors, non-2xx responses, malformed XML) are skipped by default. Provide an `onError` callback to inspect them: ```js const parser = new SitemapXMLParser('https://example.com/sitemap.xml', { onError: (url, err) => { console.error(`Skipped ${url}: ${err.message}`); }, }); ``` ## Return value `fetch()` resolves to an array of URL entry objects. Each object contains all fields present in the source XML — no field selection is applied at the library level: ```js [ { loc: 'https://example.com/page1', lastmod: '2024-01-01', changefreq: 'weekly', priority: '0.8', }, // ... ] ``` `loc` is always a string. Standard fields (`lastmod`, `changefreq`, `priority`) are strings when present, or `undefined` when absent from the source XML. Sitemap extension fields (e.g. `image:image`, `news:news`, `video:video`) are also preserved as-is when present in the source XML. Their values reflect the structure parsed by the underlying XML parser — nested elements become objects.