### Install Feedstock Dependencies Source: https://www.usefeedstock.com/llms.txt Setup commands for the Feedstock library and Playwright browsers. ```bash bun add feedstock bunx playwright install chromium ``` -------------------------------- ### Installation Source: https://www.usefeedstock.com/llms.txt Steps to install the feedstock package and its dependencies. ```APIDOC ## Installation ### Steps 1. **Install the package** ```bash bun add feedstock ``` 2. **Install Playwright browsers** ```bash bunx playwright install chromium ``` ``` -------------------------------- ### Deep Crawl - Quick Start Source: https://www.usefeedstock.com/llms.txt Basic example of initiating a deep crawl and processing results. ```APIDOC ## POST /deep-crawling ### Description Initiates a deep crawl starting from a given URL and returns a list of crawl results. ### Method POST ### Endpoint /deep-crawling ### Parameters #### Query Parameters - **url** (string) - Required - The starting URL for the crawl. - **options** (object) - Optional - Configuration for the crawl. - **cacheMode** (string) - Optional - Cache behavior (e.g., 'Bypass'). - **maxDepth** (number) - Optional - Maximum depth of links to follow (default: 3). - **maxPages** (number) - Optional - Maximum number of pages to crawl (default: 100). ### Request Example ```json { "url": "https://example.com", "options": { "cacheMode": "Bypass", "maxDepth": 2, "maxPages": 50 } } ``` ### Response #### Success Response (200) - **results** (array) - An array of crawl results. - **url** (string) - The URL of the crawled page. - **success** (boolean) - Indicates if the crawl for this page was successful. #### Response Example ```json { "results": [ { "url": "https://example.com", "success": true }, { "url": "https://example.com/page1", "success": true } ] } ``` ``` -------------------------------- ### Your First Crawl Source: https://www.usefeedstock.com/llms.txt A basic example demonstrating how to crawl a single URL and access its metadata and content. ```APIDOC ## Your First Crawl ### Description This example shows how to initialize a `WebCrawler`, crawl a single URL, and process the results. ### Request Example ```typescript import { WebCrawler } from "feedstock"; const crawler = new WebCrawler(); const result = await crawler.crawl("https://example.com"); if (result.success) { console.log("Title:", result.metadata?.title); console.log("Markdown:", result.markdown?.rawMarkdown); console.log("Links found:", result.links.internal.length); } await crawler.close(); ``` ### Response Example ```json { "success": true, "metadata": { "title": "Example Domain" }, "markdown": { "rawMarkdown": "# Example Domain\n\nThis domain is for use in illustrative examples in documents. You may use this\ncontent freely." }, "links": { "internal": [], "external": [] } } ``` ``` -------------------------------- ### Example robots.txt configuration Source: https://www.usefeedstock.com/llms.txt A sample robots.txt file demonstrating user-agent matching, allow/disallow rules, crawl delays, and sitemaps. ```text User-agent: * Disallow: /private/ Disallow: /admin Allow: /admin/public Crawl-delay: 2 User-agent: feedstock Disallow: /secret/ Allow: /secret/public/ Crawl-delay: 1 Sitemap: https://example.com/sitemap.xml ``` -------------------------------- ### Crawler Lifecycle Management Source: https://www.usefeedstock.com/llms.txt Explains how to start and close the crawler to manage browser and cache resources. ```APIDOC ## Crawler Lifecycle Management ### Description Manage the lifecycle of the `WebCrawler`. The crawler must be explicitly started before use and closed when finished to release resources. ### Method - `start()`: Launches the browser and opens the cache. - `close()`: Closes the browser and cache. ### Endpoint N/A (Instance methods) ### Request Example ```typescript await crawler.start(); // launches browser, opens cache // ... crawl pages ... await crawler.close(); // closes browser, closes cache ``` If you call `crawl()` without calling `start()` first, the crawler will auto-start. ``` -------------------------------- ### Deep Crawl - With Filters and Rate Limiting Source: https://www.usefeedstock.com/llms.txt Example showing how to configure filters (e.g., domain, content type) and rate limiting for a deep crawl. ```APIDOC ## POST /deep-crawling (with Filters and Rate Limiting) ### Description Initiates a deep crawl with advanced configurations including URL filtering and rate limiting to control the crawling process. ### Method POST ### Endpoint /deep-crawling ### Parameters #### Query Parameters - **url** (string) - Required - The starting URL for the crawl. - **options** (object) - Optional - Configuration for the crawl. - **maxDepth** (number) - Optional - Maximum depth of links to follow. - **maxPages** (number) - Optional - Maximum number of pages to crawl. - **filterChain** (object) - Optional - A chain of filters to apply to URLs. - **allowed** (array of strings) - Optional - List of allowed domains. - **contentType** (string) - Optional - Filter by content type. - **rateLimiter** (object) - Optional - Rate limiter configuration. - **baseDelay** (number) - Optional - Base delay in milliseconds between requests. - **robotsParser** (object) - Optional - Configuration for `robots.txt` compliance. ### Request Example ```json { "url": "https://example.com", "options": { "maxDepth": 2, "maxPages": 100, "filterChain": { "allowed": ["example.com"], "contentType": "text/html" }, "rateLimiter": { "baseDelay": 500 }, "robotsParser": {} } } ``` ### Response #### Success Response (200) - **results** (array) - An array of crawl results. #### Response Example ```json { "results": [ { "url": "https://example.com/page1", "success": true } ] } ``` ``` -------------------------------- ### Feedstock Crawler Setup and Imports Source: https://www.usefeedstock.com/llms.txt Imports necessary components from the Feedstock library for building a web crawler, including filters, rate limiters, and scorers. ```typescript import { WebCrawler, CacheMode, FilterChain, DomainFilter, ContentTypeFilter, URLPatternFilter, RateLimiter, RobotsParser, CompositeScorer, KeywordRelevanceScorer, PathDepthScorer, } from "feedstock"; ``` -------------------------------- ### Integrate CrawlerMonitor with a stream Source: https://www.usefeedstock.com/llms.txt Example of using the monitor within a crawler stream loop. ```typescript const monitor = new CrawlerMonitor(); monitor.start(); for await (const result of crawler.deepCrawlStream(startUrl, {}, config)) { monitor.recordPageComplete({ success: result.success, fromCache: result.cacheStatus === "hit", responseTimeMs: 0, bytesDownloaded: result.html.length, }); if (monitor.getStats().pagesTotal % 10 === 0) { console.log(monitor.formatStats()); } } ``` -------------------------------- ### Apply FilterChain with Reasons Source: https://www.usefeedstock.com/llms.txt Instantiate and use a `FilterChain` to apply multiple filters sequentially. This example demonstrates how to add filters, apply them to URLs, and retrieve all recorded denials and denials grouped by filter. ```typescript const chain = new FilterChain() .add(new DomainFilter({ allowed: ["example.com"] })) .add(new URLPatternFilter({ exclude: [/\/admin/] })) .add(new ContentTypeFilter()); // Crawl with this chain... await chain.apply("https://other.com/page"); // denied: domain await chain.apply("https://example.com/admin"); // denied: pattern await chain.apply("https://example.com/file.pdf"); // denied: content-type await chain.apply("https://example.com/docs"); // allowed // Get all denials const denials = chain.getDenials(); // [ // { url: "https://other.com/page", reason: 'Domain "other.com" is not in allowed list', filter: "domain" }, // { url: "https://example.com/admin", reason: "Matched exclude pattern: \/admin", filter: "url-pattern" }, // { url: "https://example.com/file.pdf", reason: 'File extension ".pdf" is blocked', filter: "content-type" }, // ] // Group by filter const byFilter = chain.getDenialsByFilter(); // { "domain": [...], "url-pattern": [...], "content-type": [...] } ``` -------------------------------- ### Deep Crawl - BestFirst Strategy with Scorer Source: https://www.usefeedstock.com/llms.txt Example demonstrating how to use a custom scorer to implement the BestFirst traversal strategy, prioritizing URLs based on defined criteria. ```APIDOC ## POST /deep-crawling (with BestFirst strategy) ### Description Initiates a deep crawl using the BestFirst strategy, which prioritizes URLs based on a provided scorer. ### Method POST ### Endpoint /deep-crawling ### Parameters #### Query Parameters - **url** (string) - Required - The starting URL for the crawl. - **options** (object) - Optional - Configuration for the crawl. - **maxDepth** (number) - Optional - Maximum depth of links to follow. - **maxPages** (number) - Optional - Maximum number of pages to crawl. - **scorer** (object) - Required for BestFirst - A scorer object (e.g., `CompositeScorer`) that defines prioritization logic. ### Request Example ```json { "url": "https://example.com", "options": { "maxDepth": 3, "maxPages": 50, "scorer": { "type": "CompositeScorer", "scorers": [ { "type": "KeywordRelevanceScorer", "keywords": ["docs", "api"], "weight": 2.0 }, { "type": "PathDepthScorer", "maxDepth": 10, "weight": 1.0 } ] } } } ``` ### Response #### Success Response (200) - **results** (array) - An array of crawl results, ordered by the scorer's prioritization. #### Response Example ```json { "results": [ { "url": "https://example.com/docs/api", "success": true }, { "url": "https://example.com/about", "success": true } ] } ``` ``` -------------------------------- ### Process Raw HTML Source: https://www.usefeedstock.com/llms.txt An example of processing raw HTML content directly without launching a browser. ```APIDOC ## Process Raw HTML ### Description This example demonstrates how to use `processHtml` to convert raw HTML strings into markdown without the need for a full browser instance. ### Request Example ```typescript const html = "

Hello

World

"; const result = await crawler.processHtml(html); console.log(result.markdown?.rawMarkdown); // # Hello\n\nWorld ``` ### Response Example ```json { "markdown": { "rawMarkdown": "# Hello\n\nWorld" } } ``` ``` -------------------------------- ### Manage Crawler Lifecycle Source: https://www.usefeedstock.com/llms.txt Explicitly start and close the crawler to manage browser and cache resources. ```typescript await crawler.start(); // launches browser, opens cache // ... crawl pages ... await crawler.close(); // closes browser, closes cache ``` -------------------------------- ### Apply Domain Filter with Reason Source: https://www.usefeedstock.com/llms.txt Use `applyWithReason` to get detailed denial information from a single filter. This is useful for understanding why a specific URL was rejected by a particular filter. ```typescript const filter = new DomainFilter({ allowed: ["example.com"] }); const result = await filter.applyWithReason("https://other.com/page"); console.log(result); // { // allowed: false, // reason: 'Domain "other.com" is not in allowed list', // filter: "domain" // } ``` -------------------------------- ### Integrate Table Extraction with Crawler Source: https://www.usefeedstock.com/llms.txt Examples of using the strategy within a crawler or directly via processHtml. ```typescript const result = await crawler.crawl("https://example.com/data", { extractionStrategy: { type: "css", // or use TableExtractionStrategy directly via processHtml params: { ... }, }, }); ``` ```typescript const strategy = new TableExtractionStrategy({ minRows: 2 }); const tables = await strategy.extract(result.url, result.cleanedHtml!); ``` -------------------------------- ### Combine URLSeeder with Deep Crawl Source: https://www.usefeedstock.com/llms.txt Use discovered URLs as starting points for deep crawling. ```typescript const { urls } = await seeder.seed("docs.example.com"); for (const startUrl of urls.filter(u => u.endsWith("/index.html"))) { const results = await crawler.deepCrawl(startUrl, {}, { maxDepth: 1 }); // Process results... } ``` -------------------------------- ### GET /denial-reasons Source: https://www.usefeedstock.com/llms.txt Endpoints and methods for retrieving and managing URL denial reasons during filter execution. ```APIDOC ## GET /denial-reasons ### Description Retrieves information regarding why URLs were rejected by filters. This includes per-filter reasoning and aggregated denial logs. ### Method GET ### Endpoint /denial-reasons ### Response #### Success Response (200) - **allowed** (boolean) - Whether the URL passed the filter. - **reason** (string) - The specific explanation for the rejection. - **filter** (string) - The identifier of the filter that caused the rejection. #### Response Example { "allowed": false, "reason": "Domain \"other.com\" is not in allowed list", "filter": "domain" } ``` -------------------------------- ### Basic Deep Crawl Source: https://www.usefeedstock.com/llms.txt Initiates a deep crawl from a starting URL with a specified cache mode and crawl depth/page limits. Processes results after the crawl completes. ```typescript const results = await crawler.deepCrawl( "https://example.com", { cacheMode: CacheMode.Bypass }, { maxDepth: 2, maxPages: 50 }, ); for (const result of results) { console.log(`${result.url}: ${result.success}`); } ``` -------------------------------- ### Deep Crawl - Streaming Results Source: https://www.usefeedstock.com/llms.txt Example of using streaming to process crawl results as they become available, suitable for large crawls. ```APIDOC ## POST /deep-crawling/stream ### Description Initiates a deep crawl and streams results as they are processed, allowing for real-time handling of crawled data. ### Method POST ### Endpoint /deep-crawling/stream ### Parameters #### Query Parameters - **url** (string) - Required - The starting URL for the crawl. - **options** (object) - Optional - Configuration for the crawl. - **cacheMode** (string) - Optional - Cache behavior (e.g., 'Bypass'). - **maxDepth** (number) - Optional - Maximum depth of links to follow (default: 3). - **maxPages** (number) - Optional - Maximum number of pages to crawl (default: 100). ### Request Example ```json { "url": "https://example.com", "options": { "cacheMode": "Bypass", "maxDepth": 3, "maxPages": 100 } } ``` ### Response #### Success Response (200) - **stream** (stream) - A stream of crawl result objects. - **url** (string) - The URL of the crawled page. - **success** (boolean) - Indicates if the crawl for this page was successful. #### Response Example (Streaming response, each result object is emitted as it's available) ```json { "url": "https://example.com/page1", "success": true } { "url": "https://example.com/page2", "success": false } ``` ``` -------------------------------- ### Define Custom Chunking Strategy Source: https://www.usefeedstock.com/llms.txt Create a custom chunking strategy by extending the ChunkingStrategy class and implementing the chunk method. This example splits text by sentence-ending punctuation. ```typescript import { ChunkingStrategy } from "feedstock"; class SentenceChunking extends ChunkingStrategy { chunk(text: string): string[] { return text.split(/(?<=[.!?])\s+/); } } ``` -------------------------------- ### Implement Custom JSON-LD Extraction Strategy Source: https://www.usefeedstock.com/llms.txt Extend the `ExtractionStrategy` base class to create a custom extractor. This example demonstrates parsing embedded JSON-LD scripts from HTML. ```typescript import { ExtractionStrategy, type ExtractedItem } from "feedstock"; class JsonApiExtractor extends ExtractionStrategy { async extract(url: string, html: string): Promise { // Parse embedded JSON-LD, microdata, etc. const scripts = html.match(/