<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aakash R</title>
    <description>The latest articles on DEV Community by Aakash R (@aakash_r).</description>
    <link>https://dev.to/aakash_r</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4037666%2F7724cb58-7532-4e48-aa2c-d1761a17979f.png</url>
      <title>DEV Community: Aakash R</title>
      <link>https://dev.to/aakash_r</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aakash_r"/>
    <language>en</language>
    <item>
      <title>What Is a Search API? A Complete Guide for Developers</title>
      <dc:creator>Aakash R</dc:creator>
      <pubDate>Fri, 07 Aug 2026 08:00:52 +0000</pubDate>
      <link>https://dev.to/aakash_r/what-is-a-search-api-a-complete-guide-for-developers-4dm1</link>
      <guid>https://dev.to/aakash_r/what-is-a-search-api-a-complete-guide-for-developers-4dm1</guid>
      <description>&lt;p&gt;Every day, AI assistants, chatbots, research tools, and automation workflows search the web for news, documentation, products, and other information. They rely on fresh search results to answer questions, gather information, and complete tasks. &lt;/p&gt;

&lt;p&gt;Building a search system from scratch takes time and requires continuous maintenance. A Search API provides an easy way to retrieve relevant search results through a simple API request.&lt;/p&gt;

&lt;p&gt;This guide explains what a Search API is, how it works, its common use cases, and the key factors to consider before choosing one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is a Search API?
&lt;/h2&gt;

&lt;p&gt;A Search API is a service that lets applications retrieve search results from the web through an API request. Developers send a search query along with any required parameters, and the API returns relevant results in a structured format such as JSON.&lt;/p&gt;

&lt;p&gt;The returned data can include page titles, URLs, descriptions, images, and other metadata, depending on the API. Developers use this information to build AI applications, search features, research tools, monitoring systems, and automation workflows. &lt;/p&gt;

&lt;p&gt;A Search API removes the need to build and maintain a search engine, which saves development time and effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does a Search API Work?
&lt;/h2&gt;

&lt;p&gt;A Search API follows a simple request and response process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frf89aru7w0i29gz1z8l1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frf89aru7w0i29gz1z8l1.png" alt=" " width="800" height="2112"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Send a search query&lt;/strong&gt;: The application sends a request to the Search API with a search term and optional parameters such as language, location, or the number of results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process the request&lt;/strong&gt;: The Search API searches its index or connected data sources for content that matches the query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return the results&lt;/strong&gt;: The API returns relevant search results in a structured format such as JSON. The response can include page titles, URLs, descriptions, and other metadata.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the data&lt;/strong&gt;: The application displays the results to users or uses them in another process. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, an AI assistant can answer a question using recent search results, or a research tool can collect links for further analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search API vs. Web Scraping
&lt;/h2&gt;

&lt;p&gt;Search APIs and web scraping both retrieve information from the web, but they serve different purposes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Search API&lt;/th&gt;
&lt;th&gt;Web Scraping&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Retrieves search results for a query&lt;/td&gt;
&lt;td&gt;Extracts data from specific web pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Input&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Search query&lt;/td&gt;
&lt;td&gt;Website URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Structured results in JSON&lt;/td&gt;
&lt;td&gt;Raw page content such as HTML, Markdown, or JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Source&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Search index or search engine&lt;/td&gt;
&lt;td&gt;Individual web pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Finding relevant pages and information&lt;/td&gt;
&lt;td&gt;Extracting detailed content from a webpage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Maintenance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Minimal&lt;/td&gt;
&lt;td&gt;May require updates if the website structure changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Common Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI assistants, search tools, market research, SEO&lt;/td&gt;
&lt;td&gt;Price monitoring, product data extraction, news scraping, content collection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;When to Use a Search API&lt;/strong&gt;&lt;br&gt;
Use a Search API when you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find relevant web pages based on a search query.&lt;/li&gt;
&lt;li&gt;Retrieve structured search results.&lt;/li&gt;
&lt;li&gt;Build AI assistants or search features.&lt;/li&gt;
&lt;li&gt;Search across multiple websites.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to Use Web Scraping&lt;/strong&gt;&lt;br&gt;
Use web scraping when you need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract content from a specific webpage.&lt;/li&gt;
&lt;li&gt;Collect product details, prices, or reviews.&lt;/li&gt;
&lt;li&gt;Retrieve tables, articles, or structured data from websites.&lt;/li&gt;
&lt;li&gt;Gather data for analytics or research.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Many applications use both together. A Search API finds relevant pages, and a web scraping API extracts detailed content from those pages. This approach works well for AI applications, research tools, and market intelligence platforms.&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Use Cases of a Search API
&lt;/h2&gt;

&lt;p&gt;Search APIs support many applications across different industries. Here are some common use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI agents&lt;/strong&gt;: Retrieve current information from the web to complete tasks, answer questions, and make decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval Augmented Generation (RAG)&lt;/strong&gt;: Search for relevant documents or web pages and use them as context before generating responses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chatbots&lt;/strong&gt;: Search documentation, knowledge bases, or the web to answer user queries with relevant information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO tools&lt;/strong&gt;: Analyze search results, track keyword rankings, and monitor competitors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Price monitoring&lt;/strong&gt;: Search e-commerce websites to compare product prices and monitor price changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;News aggregation&lt;/strong&gt;: Collect news articles from multiple publishers and display them in a single application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market research&lt;/strong&gt;: Track competitors, products, customer reviews, and industry trends from different sources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser extensions&lt;/strong&gt;: Retrieve search results directly within the browser to provide quick answers or additional information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation workflows&lt;/strong&gt;: Search the web as part of automated tasks such as lead generation, content collection, or data validation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise search&lt;/strong&gt;: Search internal documents, knowledge bases, wikis, and company resources from a single interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What to Look for in a Search API
&lt;/h2&gt;

&lt;p&gt;Choosing the right Search API depends on your application's requirements. The quality of search results should be your first consideration. A good Search API returns relevant and accurate results for different types of queries and provides structured data in formats such as JSON for easy integration.&lt;/p&gt;

&lt;p&gt;Performance is another important factor. Look for an API that offers fast response times, supports search filters such as language, region, and date, and allows you to control the number of results returned. If your application targets users in specific countries, geographic search support is also valuable.&lt;/p&gt;

&lt;p&gt;You should also evaluate practical aspects such as rate limits, pricing, documentation, and SDK availability. Clear documentation and code examples make integration easier, while reliable uptime and responsive technical support help keep your application running smoothly.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to Use a Search API
&lt;/h2&gt;

&lt;p&gt;Most Search APIs follow a simple request and response process. You send a search query with your API key, and the API returns matching results in a structured format such as JSON.&lt;/p&gt;

&lt;p&gt;Many Search APIs are available, so choose one that fits your requirements. I'll use the &lt;a href="https://geekflare.com/search/" rel="noopener noreferrer"&gt;Geekflare Search API&lt;/a&gt; because it is easy to integrate, supports MCP, and provides SDKs and examples for Python, Node.js, React, PHP, and cURL. &lt;/p&gt;

&lt;p&gt;After creating a &lt;a href="https://dash.geekflare.com/dashboard" rel="noopener noreferrer"&gt;Geekflare account&lt;/a&gt;, you can find your API key in the dashboard and start sending requests with just a few lines of code.&lt;/p&gt;

&lt;p&gt;If you need the content from the search results, Geekflare's Extract API returns web pages in HTML, Markdown, JSON, Text, and TextLLM formats, making it useful for AI applications and automation workflows.&lt;/p&gt;

&lt;p&gt;The example below sends a search request to the Geekflare Search API and returns the matching results in JSON format.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Install the Geekflare Python SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install geekflare-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the required modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from geekflare_api.client import GeekflareClient
from geekflare_api.models import SearchDto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example below searches for "&lt;strong&gt;Best LLM providers&lt;/strong&gt;" using the Geekflare Search API and returns the results in JSON format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from geekflare_api.client import GeekflareClient
from geekflare_api.models import SearchDto

with GeekflareClient(api_key="YOUR_API_KEY") as client:
    result = client.search(
        SearchDto(
            location="us",
            source="web",
            category="general",
            format="json",
            grounded_answer=True,
            query="best llm providers",
            scrape=False
        )
    )
    print(result)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Search API Parameters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;query&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Search query to execute.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;location&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;ISO 3166-1 alpha-2 country code used to localize search results (for example, &lt;code&gt;us&lt;/code&gt;, &lt;code&gt;uk&lt;/code&gt;, or &lt;code&gt;in&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;source&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Search source. Supported values include &lt;code&gt;web&lt;/code&gt;, &lt;code&gt;news&lt;/code&gt;, and &lt;code&gt;images&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Filters results by category, such as &lt;code&gt;general&lt;/code&gt;, &lt;code&gt;code&lt;/code&gt;, &lt;code&gt;pdf&lt;/code&gt;, &lt;code&gt;research&lt;/code&gt;, &lt;code&gt;linkedin&lt;/code&gt;, or &lt;code&gt;wiki&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;format&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Response format. Supported values are &lt;code&gt;json&lt;/code&gt;, &lt;code&gt;markdown&lt;/code&gt;, and &lt;code&gt;html&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;grounded_answer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;Returns an AI-generated grounded answer based on the search results.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;scrape&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;Extracts content from the top search results when set to &lt;code&gt;true&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Response
&lt;/h3&gt;

&lt;p&gt;After sending the request, the Search API returns the matching results in JSON format. The response includes the search results along with details such as the page title, URL, ranking position, and other metadata.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm1lm3ujzym4w8undhr7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm1lm3ujzym4w8undhr7z.png" alt=" " width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The returned JSON can be parsed to access individual fields such as &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;url&lt;/code&gt;, and &lt;code&gt;position&lt;/code&gt;. You can then display the results in your application or pass them to another API for further processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use the Search API with Geekflare Playground
&lt;/h2&gt;

&lt;p&gt;Geekflare also provides a no-code platform called Geekflare Playground for testing its APIs. You can use it to explore the Search API before integrating it into your application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign in to your &lt;a href="https://docs.geekflare.com/api/api-playground" rel="noopener noreferrer"&gt;Geekflare account&lt;/a&gt; and open Geekflare Playground.&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Search API&lt;/strong&gt; and enter your search query.&lt;/li&gt;
&lt;li&gt;Configure the request by setting options such as &lt;strong&gt;Grounded Answer&lt;/strong&gt;, &lt;strong&gt;Scrape&lt;/strong&gt;, &lt;strong&gt;Results&lt;/strong&gt;, &lt;strong&gt;Result Limit&lt;/strong&gt;, &lt;strong&gt;Time Filter&lt;/strong&gt;, &lt;strong&gt;Country, Source&lt;/strong&gt;, &lt;strong&gt;Category&lt;/strong&gt;, and &lt;strong&gt;Response Format&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Add domains to include or exclude if you want to narrow the search.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Send Request&lt;/strong&gt; to view the API response instantly.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Get Code&lt;/strong&gt; to generate code snippets for &lt;code&gt;Python&lt;/code&gt;, &lt;code&gt;Node.js&lt;/code&gt;,  &lt;code&gt;PHP&lt;/code&gt;, and &lt;code&gt;cURL&lt;/code&gt; for easy integration into your application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the workflow:&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/JXKn7PTDdhc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Popular Search APIs
&lt;/h2&gt;

&lt;p&gt;Several Search APIs are available today, and each serves different use cases. Some focus on general web search, others support AI applications, and some specialize in search engine results or custom website search.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Search API&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;th&gt;Key Features&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Geekflare Search API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI applications, automation, developer tools&lt;/td&gt;
&lt;td&gt;SDKs for Python, Node.js, React, PHP, and cURL, MCP support, no-code Playground, grounded answers, Extract API integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Google Custom Search JSON API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Custom website search&lt;/td&gt;
&lt;td&gt;Google Programmable Search Engine, JSON responses, customizable search experience&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bing Web Search API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;General web search&lt;/td&gt;
&lt;td&gt;Web, image, news, and video search, Microsoft ecosystem integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Brave Search API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Privacy-focused applications&lt;/td&gt;
&lt;td&gt;Independent search index, web search, AI-ready results&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SerpAPI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SEO and SERP analysis&lt;/td&gt;
&lt;td&gt;Google, Bing, Yahoo, Baidu, and other search engine results, structured JSON responses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tavily Search API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AI agents and LLMs&lt;/td&gt;
&lt;td&gt;Real-time search, grounded answers, optimized for AI workflows&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Choose a Search API based on your application's requirements, supported features, pricing, documentation, and ease of integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing the Right Search API
&lt;/h2&gt;

&lt;p&gt;The right Search API depends on your application's requirements. Before choosing one, consider the following factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search quality&lt;/strong&gt;: Returns relevant and accurate results for different queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response time&lt;/strong&gt;: Delivers results quickly for a better user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search filters&lt;/strong&gt;: Supports filters such as language, country, category, and date.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response format&lt;/strong&gt;: Returns structured data in formats such as JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK support&lt;/strong&gt;: Provides SDKs for languages such as Python, Node.js, React, PHP, and cURL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: Includes clear guides, code examples, and API references.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI support&lt;/strong&gt;: Offers features such as grounded answers and MCP integration for AI applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pricing&lt;/strong&gt;: Matches your usage requirements and budget.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Search APIs simplify the process of retrieving information from the web. They help developers build AI applications, chatbots, research tools, automation workflows, and search features by returning structured search results through a simple API request.&lt;/p&gt;

&lt;p&gt;Choosing the right Search API depends on your project's requirements, including search quality, response format, performance, documentation, pricing, and integration options. &lt;/p&gt;

&lt;p&gt;Compare the available solutions, explore their features, and select the one that best fits your application and development workflow.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>automation</category>
      <category>api</category>
    </item>
    <item>
      <title>Why Every RAG Application Needs a Web Scraping API</title>
      <dc:creator>Aakash R</dc:creator>
      <pubDate>Wed, 22 Jul 2026 02:45:03 +0000</pubDate>
      <link>https://dev.to/aakash_r/why-every-rag-application-needs-a-web-scraping-api-4d5a</link>
      <guid>https://dev.to/aakash_r/why-every-rag-application-needs-a-web-scraping-api-4d5a</guid>
      <description>&lt;p&gt;I have been exploring RAG applications recently. The more I worked with them, the more I realized that building a RAG pipeline feels more approachable than many people think. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fie96w13btc2eh3c5vgl1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fie96w13btc2eh3c5vgl1.jpg" alt=" " width="600" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The bigger challenge came from the knowledge base. The quality of a RAG application depends on the content you feed into it. Getting content from websites is not always simple. Modern websites rely on JavaScript and anti bot protection. Inconsistent output adds another layer of complexity. I also needed clean Markdown that an LLM could process directly.&lt;/p&gt;

&lt;p&gt;After trying a few options, I found the Geekflare Web Scraping API. It checked the boxes I was looking for, so I decided to build my RAG application with it. In this tutorial, &lt;/p&gt;

&lt;p&gt;I will walk through the steps I followed to scrape website content, build a ChromaDB knowledge base, and create a simple RAG application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Role of Web Scraping in RAG
&lt;/h2&gt;

&lt;p&gt;Every RAG application follows a simple workflow. It starts with content collection, followed by embedding generation and vector storage. User queries retrieve the most relevant content before the LLM generates a response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpqrsim4zlg0ad6l5267.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpqrsim4zlg0ad6l5267.png" alt="RAG Workflow" width="800" height="1251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Content collection becomes the foundation of the entire pipeline. Missing sections, incomplete pages, or noisy text reduce retrieval quality. A better knowledge base usually produces better answers.&lt;/p&gt;

&lt;p&gt;For this project, website content comes from the&lt;a href="https://geekflare.com/" rel="noopener noreferrer"&gt; Geekflare Web Scraping API&lt;/a&gt;. The API returns Markdown, the content moves into ChromaDB for embedding storage, and the retrieved documents provide context for the LLM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;In this tutorial, we will build a simple RAG application that answers questions using website content. .&lt;/p&gt;

&lt;p&gt;The workflow looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scrape website content&lt;/li&gt;
&lt;li&gt;Generate embeddings&lt;/li&gt;
&lt;li&gt;Store embeddings in ChromaDB&lt;/li&gt;
&lt;li&gt;Retrieve relevant content&lt;/li&gt;
&lt;li&gt;Generate a response with the LLM&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before you begin, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python 3.10 or later&lt;/li&gt;
&lt;li&gt;A Geekflare API key&lt;/li&gt;
&lt;li&gt;An API key for your preferred LLM provider&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you don't have a Geekflare API key yet, visit &lt;a href="https://dash.geekflare.com/" rel="noopener noreferrer"&gt;Geekflare&lt;/a&gt;, sign in to your account, open the dashboard, and copy your API key.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install the Required Libraries
&lt;/h3&gt;

&lt;p&gt;Install the libraries required for web scraping, vector storage, embedding generation, environment variable management, and LLM integration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;geekflare-api chromadb sentence-transformers python-dotenv openai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in the project root and add your API keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;GEEKFLARE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_geekflare_api_key
&lt;span class="nv"&gt;LLM_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_llm_api_key
&lt;span class="nv"&gt;LLM_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_llm_base_url
&lt;span class="nv"&gt;LLM_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_model_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the RAG Application
&lt;/h2&gt;

&lt;p&gt;Now that the project is set up, let's build the RAG pipeline. We'll start by importing the required libraries, initializing the embedding model, vector database, and LLM client. &lt;/p&gt;

&lt;p&gt;We'll also create helper functions for scraping website content, generating embeddings, retrieving relevant documents, and generating responses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;geekflare_api.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GeekflareClient&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;geekflare_api.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;WebScrapeDto&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sentence_transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SentenceTransformer&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="c1"&gt;# Load environment variables
&lt;/span&gt;&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the embedding model
&lt;/span&gt;&lt;span class="n"&gt;embedding_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;SentenceTransformer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all-MiniLM-L6-v2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize ChromaDB
&lt;/span&gt;&lt;span class="n"&gt;chroma_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chromadb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chroma_client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_or_create_collection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;website_knowledge&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the LLM client
&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLM_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLM_BASE_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;LLM_MODEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLM_MODEL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Scrape&lt;/span&gt; &lt;span class="n"&gt;Website&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first step is to collect the website content. The function below sends the target URL to the Geekflare Web Scraping API and returns the page in Markdown format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;scrape_website&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Scrape a website and return Markdown content.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nc"&gt;GeekflareClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GEEKFLARE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;web_scrape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;WebScrapeDto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;markdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="n"&gt;render_js&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;block_ads&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scrape failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;markdown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Split the Content into Chunks
&lt;/h3&gt;

&lt;p&gt;Embedding an entire webpage at once isn't practical. Instead, split the content into smaller chunks before generating embeddings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;split_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Split text into chunks.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Generate&lt;/span&gt; &lt;span class="n"&gt;Embeddings&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Store&lt;/span&gt; &lt;span class="n"&gt;Them&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ChromaDB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, convert each chunk into an embedding and store it in ChromaDB. These embeddings will be used later to retrieve the most relevant content for a user query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Generate embeddings and store them in ChromaDB.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embedding_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;doc_&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Retrieve Relevant Context
&lt;/h3&gt;

&lt;p&gt;When a user asks a question, convert it into an embedding and search ChromaDB for the most relevant chunks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Retrieve the most relevant chunks.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;query_embedding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embedding_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;query_embeddings&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;query_embedding&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;n_results&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;documents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generate the Response
&lt;/h3&gt;

&lt;p&gt;Finally, combine the retrieved context with the user's question and send it to your preferred LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ask_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Generate a response using the retrieved context.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
Answer the question using only the context below.

Context:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;

Question:
&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;LLM_MODEL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;role&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;content&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run the Application
&lt;/h3&gt;

&lt;p&gt;The main() function ties everything together. It scrapes the website, builds the knowledge base, and starts an interactive question answering session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Website URL: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Scraping website...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;markdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;scrape_website&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Creating embeddings...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;split_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;markdown&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;store_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Knowledge base ready.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ask a question (or &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;): &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;retrieve_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ask_llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Answer:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can get the entire code here: &lt;a href="https://github.com/geekflare/geekflare-snippets/blob/stable/rag-with-web-scrapping.py" rel="noopener noreferrer"&gt;https://github.com/geekflare/geekflare-snippets/blob/stable/rag-with-web-scrapping.py&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the Application
&lt;/h2&gt;

&lt;p&gt;Run the script and enter the URL of the website you want to use as the knowledge base. You can use any publicly accessible website, such as documentation, blogs, news articles, or Wikipedia pages. &lt;/p&gt;

&lt;p&gt;I used a &lt;a href="https://en.wikipedia.org/wiki/Tropical_Storm_Brenda_(1960)" rel="noopener noreferrer"&gt;Wikipedia page about Tropical Storm Brenda (1960)&lt;/a&gt; for this example.&lt;/p&gt;

&lt;p&gt;You can also use any OpenAI-compatible LLM provider. In this tutorial, I used &lt;code&gt;Gemini 2.5 Flash&lt;/code&gt;, but you can switch to OpenAI, Grok, or any other compatible model by updating the values in your &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzsbvtxl2h38rgqh4vfy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffzsbvtxl2h38rgqh4vfy.png" alt=" " width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, type &lt;code&gt;exit&lt;/code&gt; to end the application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's it! You now have a simple RAG application that scrapes website content with the &lt;a href="https://geekflare.com/webscraping/" rel="noopener noreferrer"&gt;Geekflare Web Scraping API&lt;/a&gt;, stores embeddings in ChromaDB, and answers questions using an LLM.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faxp6qfphwz0ga0ef6y69.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faxp6qfphwz0ga0ef6y69.gif" alt=" " width="427" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This example uses a single webpage, but you can extend it to index multiple pages, documentation sites, blogs, or your own knowledge base. &lt;/p&gt;

&lt;p&gt;Since the LLM provider is configurable through environment variables, you can also switch between Gemini, OpenAI, Grok, or any other OpenAI-compatible model without changing the application code.&lt;/p&gt;

</description>
      <category>rag</category>
      <category>webdev</category>
      <category>webscraping</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
