Skip to content

How to Scrape Data From a Website: 4 Methods, No-Code to Python

How to scrape data from a website four ways: a ready-made scraper with no code, a generic cloud scraper with one extraction function, a Python script you run yourself, and an AI agent over MCP. Each with real runs, exact costs and tested code.

Published
Reading time
9 min read
Pixel-art robot with an orange >_ on its terminal head pulls a data card out of a browser window showing a web page and drops it into a crate of collected data
In this article
  1. How to scrape data from a website: 4 methods at a glance
  2. Before you start: three quick checks
  3. Method 1: Use a ready-made scraper (no code)
  4. Method 2: Use a generic cloud scraper (one function)
  5. Web Scraper: four book pages in 12 seconds
  6. Website Content Crawler: a whole site as text
  7. Method 3: Write a Python scraper
  8. Method 4: Ask an AI agent over MCP
  9. Which method should you use?
  10. What to watch out for
  11. FAQ
  12. Can I scrape data from any website?
  13. How do I scrape a website without coding?
  14. Is it legal to scrape data from a website?
  15. How do I scrape a website that uses JavaScript?
  16. How much does it cost to scrape a website?

How to scrape data from a website comes down to one decision: build the scraper yourself, or use one that already exists. If a ready-made scraper covers the site, you can have a spreadsheet in under a minute without code; if not, a generic cloud scraper, a short Python script or an AI agent will get the data.

This guide walks through all four methods, from no-code to Python, on real targets. Every run below happened on 22 or 23 October 2026, and every cost is what we were actually charged.

How to scrape data from a website: 4 methods at a glance

  1. Ready-made scraper
  1. Generic cloud scraper
  1. Python script
  1. AI agent over MCP
You need A browser A few CSS selectors Python and some HTML An AI assistant such as Claude or Cursor
Your work Fill in a form Write one extraction function Write, run and host the whole scraper Describe the data in a sentence
Proxies, retries, hosting Included Included Yours to build Included
Who fixes it when the site changes The scraper's maintainer You (one function) You The maintainer of the Actor the agent uses
Best for Big platforms: Google Maps, Amazon, LinkedIn, Reddit Any public site without a dedicated scraper Learning, one-off jobs, full control Ad hoc questions and agent workflows
Example cost 10 places for $0.037 4 pages for $0.0029 Free, plus your time and servers Same as the Actor it runs

Before you start: three quick checks

  1. Is the data public? Stick to what a logged-out visitor can see. Data behind a login comes with terms you accepted, and personal data comes with privacy law. Our web scraping guide covers the basics.
  2. Does a scraper already exist? Search the Scrape.ly Store for the site's name. If there's a match, method 1 is the fastest route by far.
  3. Is the data in the HTML? Open the page, right-click, choose View page source and search for a value you want, such as a price. If it's there, plain HTTP scraping works. If it isn't, the page builds its content with JavaScript and you need a browser or the page's own data request.

Method 1: Use a ready-made scraper (no code)

The Scrape.ly Store has 568 Actors, each a maintained scraper for one site or job. You fill in a form, start the run and download the results. Nothing to install, and when the site changes its layout, the Actor's maintainer updates it.

Here's the whole process with the Google Maps Scraper:

  1. Open the Actor page and pick the preset Restaurants in Konstanz, 10 places. It fills the form with this input:
json
{
  "searchStringsArray": ["restaurant"],
  "locationQuery": "Konstanz",
  "maxCrawledPlacesPerSearch": 10,
  "language": "en"
}
  1. Click Start. Our run on 22 October 2026 took 5.7 seconds and saved 10 places:
Text
2026-10-22T15:22:55.025Z [scrapely.actor] INFO  Saved 10 places in 3.2s (11 requests, 0 hedged, 0.93 MB); start-up: python 1.13s, SDK import 0.00s, SDK init 0.27s
  1. Open the results and export them as CSV, Excel or JSON. The first three rows:
Name Category Rating Reviews Street
The Dom Italian restaurant 4.7 1,136 Brückengasse 1
Constanzer Wirtshaus German restaurant 4.4 7,521 Spanierstraße 3
Chu Minh Restaurant Asian restaurant 4.7 249 Frieda-Sigrist-Weg 1

Each record also carries the phone number, website, opening hours, coordinates and more. The run cost $0.036888: 10 places × $0.0036 = $0.036 in place fees, plus $0.0009 of compute and proxy. The free plan's $5 monthly credit covers about 1,350 places at that rate.

To change the job, edit the search term, location and limit, and click Start again. To repeat it every morning, add a schedule under Automations.

Method 2: Use a generic cloud scraper (one function)

When no Actor exists for your site, a generic scraper does the fetching, link following, proxies and retries, and you supply only the extraction logic. Scrape.ly has two:

  • Web Scraper runs your JavaScript page function on each page and saves whatever object it returns. Best for structured fields: prices, titles, specs. $0.50 per 1,000 results.
  • Website Content Crawler crawls a site from a start URL or its sitemap and saves each page's clean text and Markdown. Best for documentation, knowledge bases and LLM pipelines. $0.50 per 1,000 pages.

Web Scraper: four book pages in 12 seconds

We pointed the Web Scraper at the Mystery category of books.toscrape.com, a sandbox shop built for scraping practice, and told it to follow each book link and pull four fields from the book page:

json
{
  "startUrls": [{ "url": "https://books.toscrape.com/catalogue/category/books/mystery_3/index.html" }],
  "linkSelector": "article.product_pod h3 a",
  "globs": [{ "glob": "https://books.toscrape.com/catalogue/*/index.html" }],
  "pageFunction": "async function pageFunction(context) {\n  const $ = context.jQuery;\n  if (!$('div.product_main').length) return null;\n  return {\n    url: context.request.url,\n    title: $('div.product_main h1').text().trim(),\n    price: $('div.product_main p.price_color').text().trim(),\n    inStock: $('div.product_main p.availability').text().includes('In stock'),\n    upc: $('table.table-striped td').first().text().trim()\n  };\n}",
  "maxPagesPerCrawl": 6,
  "maxResultsPerCrawl": 5,
  "maxConcurrency": 2,
  "respectRobotsTxtFile": true,
  "proxyConfiguration": { "useScrapelyProxy": true }
}

The fields that matter:

  • linkSelector and globs decide which links get followed: here only the book links on the listing page.
  • pageFunction gets jQuery on each page. On the listing page it returns null, so the page is only used to find links; on a book page it returns the record.
  • maxResultsPerCrawl stops the run after five records; maxConcurrency keeps the load on the site low.
  • respectRobotsTxtFile skips links the site's robots.txt disallows.

The run on 23 October 2026 fetched 5 pages and saved 4 book records in 12 seconds:

Text
2026-10-23T03:02:50.015Z [scrapely.proxy_configuration] INFO  Platform proxy access check succeeded.
2026-10-23T03:02:58.070Z [scrapely.actor] INFO  Done: 5 pages fetched, 4 records saved in 8 s
Title Price In stock UPC
Sharp Objects £47.82 Yes e00eb4fd7b871a48
In a Dark, Dark Wood £19.63 Yes 19ed25f4641d5efd
The Past Never Ends £56.50 Yes 5ee94540d0749ea0
A Murder in Time £16.64 Yes f733e8c19d40ec2e

It was charged $0.002919: 4 results × $0.0005 = $0.002, plus $0.0009 of compute, proxy and storage. The listing page's null record wasn't charged. For pages that only show data after JavaScript runs, set "useChrome": true and the same page function runs on the rendered page.

Website Content Crawler: a whole site as text

If you want every page's text rather than specific fields, the crawler is simpler: give it a start URL and a page cap. On 22 October 2026 it read crawlee.dev's sitemaps (4,860 pages listed) and saved the first 5 pages as clean text and Markdown in 6.2 seconds, for $0.0031. Runs that short can use the synchronous endpoint, which returns the items in the same response:

shell
curl -X POST "https://api.scrape.ly/v2/actors/querystone~website-content-crawler/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $SCRAPELY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"startUrls": [{"url": "https://crawlee.dev/"}], "useSitemaps": true, "maxCrawlPages": 5, "maxResults": 5}'

Create the token under Settings → API & Integrations and export it as SCRAPELY_TOKEN. Add "includeUrlGlobs" to keep the crawl inside one section, such as /docs/.

Method 3: Write a Python scraper

Code gives you full control and costs nothing but time. This script scrapes every book in the same Mystery category, pages through the results by following the "next" link, and writes a CSV. Install the libraries with pip install requests beautifulsoup4:

python
import csv
import time
from urllib.parse import urljoin

import requests
from bs4 import BeautifulSoup

START = "https://books.toscrape.com/catalogue/category/books/mystery_3/index.html"
RATINGS = {"One": 1, "Two": 2, "Three": 3, "Four": 4, "Five": 5}

session = requests.Session()
session.headers["User-Agent"] = "books-scraper/1.0 (+mailto:you@example.com)"

def scrape_listing(url):
    """Return the books on one listing page and the URL of the next page (or None)."""
    soup = BeautifulSoup(session.get(url, timeout=15).content, "html.parser")
    rows = []
    for book in soup.select("article.product_pod"):
        link = book.select_one("h3 a")
        rows.append({
            "title": link["title"],
            "price_gbp": float(book.select_one("p.price_color").get_text(strip=True).lstrip("£")),
            "rating": RATINGS[book.select_one("p.star-rating")["class"][1]],
            "in_stock": "In stock" in book.select_one("p.availability").get_text(),
            "url": urljoin(url, link["href"]),
        })
    next_link = soup.select_one("li.next a")
    return rows, urljoin(url, next_link["href"]) if next_link else None

books, url = [], START
while url:
    rows, url = scrape_listing(url)
    books.extend(rows)
    time.sleep(1)  # be polite: one page per second

with open("books.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=books[0].keys())
    writer.writeheader()
    writer.writerows(books)

print(f"Saved {len(books)} books to books.csv")
print(books[0])

We ran it on 23 October 2026 with Python 3.12, requests 2.34 and Beautiful Soup 4.15:

Text
Saved 32 books to books.csv
{'title': 'Sharp Objects', 'price_gbp': 47.82, 'rating': 4, 'in_stock': True, 'url': 'https://books.toscrape.com/catalogue/sharp-objects_997/index.html'}

How it works:

  • Selectors. Each book sits in an article.product_pod. The full title is in the link's title attribute; the star rating is a CSS class (star-rating Four), so a small dictionary turns it into a number.
  • Pagination. li.next a holds the next page's relative URL; urljoin makes it absolute. When there's no next link, the loop ends. The category has 32 books on two pages.
  • Politeness. A shared session reuses the connection, the User-Agent says who you are, and time.sleep(1) keeps it to one request per second.
  • Clean output. Prices become floats and ratings become integers before they reach the CSV, so the file opens correctly in Excel or pandas.

When the data only appears after JavaScript runs, swap requests for Playwright, which drives a real Chromium. Our Python web scraping guide covers Playwright, Scrapy and the trade-offs.

The hard part of this method comes later: running it every day, rotating proxies when the site starts answering 429, and noticing when a redesign quietly returns empty fields. You can host the script on Scrape.ly to get the scheduling, proxies and storage: start from the Python + Beautiful Soup template and push it with the CLI.

Method 4: Ask an AI agent over MCP

AI assistants can scrape too, if you give them a tool. The Scrape.ly MCP server lets Claude, Cursor, VS Code, ChatGPT and other MCP clients search the Store, read an Actor's input schema, run it and read the results. In Cursor, add it to ~/.cursor/mcp.json:

json
{
  "mcpServers": {
    "scrapely": {
      "url": "https://api.scrape.ly/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

In Claude Code, run claude mcp add --transport http scrapely https://api.scrape.ly/mcp and sign in with /mcp. Then ask in plain words:

Use scrapely to run cornerledger/google-maps-scraper for restaurants in Konstanz, 10 places, and give me a CSV of name, rating and phone.

The agent calls search-actors or goes straight to the named Actor, reads its schema with fetch-actor-details, starts it with call-actor and fetches the rows with get-actor-output. Runs started through MCP are normal runs on your account, charged at the Actor's usual price. For agents that should never overspend, give them a scoped API key with a daily charge limit, and they can pass maxTotalChargeUsd on each call. See Scrape.ly MCP for the client list.

Which method should you use?

  • The site is a big platform (Google, Amazon, LinkedIn, Instagram, Zillow): method 1. Platforms change often and block aggressively, and a maintained Actor absorbs both.
  • The site is a niche shop, directory or catalogue: method 2 with the Web Scraper, or method 3 if you want the code in your own repo.
  • You need a whole site's text for search or an LLM: the Website Content Crawler.
  • You're answering a question, not building a pipeline: method 4.
  • You want the data in a spreadsheet: any of the four works. Store runs export CSV and Excel directly, and the Python script writes a CSV.

What to watch out for

  • Empty results. The usual cause is JavaScript rendering. Check the page source first; switch to useChrome or Playwright if the data isn't there.
  • Blocking and 429 errors. Slow down, reduce concurrency, and use proxies. Store Actors and the generic scrapers include them.
  • Silent breakage. A redesign can leave your scraper "working" while every price comes back empty. Check field counts on every run.
  • Runaway costs. Set the Actor's own limit (such as maxResultsPerCrawl) and a maximum charge for the run. The run stops when it reaches the cap.
  • Personal data and terms. Scrape public pages, collect only the fields you need, and don't scrape behind a login you agreed terms for.

FAQ

Can I scrape data from any website?

Technically you can fetch any public page, but some sites block bots heavily, and some data is off-limits because it's behind a login or is personal data you have no basis to collect. Public product, business, job and news data is the common, low-risk case.

How do I scrape a website without coding?

Use a ready-made scraper: find the site in the Scrape.ly Store, fill in the form or pick a preset, click Start and export the results as CSV, Excel or JSON. For sites without a dedicated scraper, the Web Scraper only needs a short extraction function.

Scraping publicly available data is common and lawful in many contexts, but terms you accepted, privacy law and copyright still apply. Our guide is web scraping legal? explains the rules and court cases. This is general information, not legal advice.

How do I scrape a website that uses JavaScript?

Either find the JSON request the page makes in your browser's developer tools and call it directly, or use a real browser: Playwright or Selenium in your own code, or useChrome in the Scrape.ly Web Scraper.

How much does it cost to scrape a website?

Your own script costs only time and hosting. On Scrape.ly you pay per result at the price shown on each Actor page: $0.50 per 1,000 results for the Web Scraper and $3.60 per 1,000 places for the Google Maps Scraper, plus small platform usage. The free plan includes $5 of usage every month.

  • web scraping
  • how to scrape a website
  • python
  • no-code
  • mcp
  • beautifulsoup

About the author

The team behind Scrape.ly

Scrape.ly is the web data platform from TeraShift GmbH in Switzerland, powered by Evomi: ready-made scrapers in the Scrape.ly Store, a cloud runtime, an API with JavaScript and Python SDKs, proxies, a hosted anti-bot browser and an MCP server for AI agents.

//Keep reading\\

The internet is full of data.
Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

No credit card. No setup calls.