Fiverr is a goldmine of freelance market data — gig prices, seller ratings, delivery times, service categories, and buyer reviews. Whether you're researching freelance pricing trends, building a competitor analysis tool, or studying the gig economy, scraping Fiverr gives you structured data that their platform doesn't expose through any public API.
In this guide, I'll show you how to scrape Fiverr gig listings, seller profiles, and reviews with Python. I'll cover what works, what breaks, and how to handle Fiverr's anti-bot measures.
What Data Can You Extract from Fiverr?
Here's what's available on public Fiverr pages:
- Gig listings — title, description, pricing tiers (Basic/Standard/Premium), delivery time
- Seller profiles — username, level (New/Level 1/2/Top Rated), response time, country, member since
- Reviews — star rating, review text, buyer country, date
- Category data — subcategories, number of services available
- Search results — gigs ranked by relevance/best selling/newest for any keyword
Step 1: Understanding Fiverr's URL Structure
Fiverr search URLs are straightforward:
https://www.fiverr.com/search/gigs?query=web+scraping&source=top-bar&ref_ctx_id=...&page=1
Key parameters:
-
query— search keywords -
page— pagination (starts at 1) -
category_id— filter by category -
delivery_time— filter by delivery speed
Individual gig pages follow the pattern:
https://www.fiverr.com/{seller_username}/{gig_slug}
Step 2: Scraping Search Results
Fiverr's search results render with JavaScript, but the initial HTML contains enough structured data to get started. Here's a scraper for gig listings:
import requests
from bs4 import BeautifulSoup
import json
import time
import random
import csv
def scrape_fiverr_search(query, pages=3):
"""Scrape Fiverr search results for gig listings."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Referer": "https://www.fiverr.com/",
}
all_gigs = []
for page in range(1, pages + 1):
url = f"https://www.fiverr.com/search/gigs?query={query}&page={page}"
response = requests.get(url, headers=headers, timeout=30)
if response.status_code != 200:
print(f"Page {page}: Status {response.status_code}")
continue
soup = BeautifulSoup(response.text, "html.parser")
# Fiverr embeds gig data in JSON within the page
# Look for the Next.js data script
for script in soup.select('script[id="__NEXT_DATA__"]'):
try:
data = json.loads(script.string)
gigs_data = (
data.get("props", {})
.get("pageProps", {})
.get("searchResults", {})
.get("gigs", [])
)
for gig in gigs_data:
parsed = {
"title": gig.get("title"),
"seller": gig.get("seller", {}).get("username"),
"seller_level": gig.get("seller", {}).get("level"),
"seller_country": gig.get("seller", {}).get("country"),
"price": gig.get("price"),
"currency": gig.get("currency"),
"rating": gig.get("rating"),
"reviews_count": gig.get("reviews_count"),
"delivery_time": gig.get("delivery_time"),
"gig_url": f"https://www.fiverr.com{gig.get('url', '')}",
}
all_gigs.append(parsed)
except (json.JSONDecodeError, TypeError, KeyError):
continue
# Fallback: parse HTML directly if JSON isn't available
if not all_gigs:
gig_cards = soup.select('.gig-card-layout')
for card in gig_cards:
gig = {}
title_el = card.select_one('.text-display-7')
gig["title"] = title_el.get_text(strip=True) if title_el else None
seller_el = card.select_one('.seller-name')
gig["seller"] = seller_el.get_text(strip=True) if seller_el else None
price_el = card.select_one('.price')
gig["price"] = price_el.get_text(strip=True) if price_el else None
rating_el = card.select_one('.rating-score')
gig["rating"] = rating_el.get_text(strip=True) if rating_el else None
link_el = card.select_one('a[href*="/"]')
gig["gig_url"] = f"https://www.fiverr.com{link_el['href']}" if link_el else None
if gig["title"]:
all_gigs.append(gig)
print(f"Page {page}: Found {len(all_gigs)} gigs total")
time.sleep(random.uniform(3, 6))
return all_gigs
# Usage
gigs = scrape_fiverr_search("web+scraping", pages=3)
print(f"\nFound {len(gigs)} gigs")
for g in gigs[:5]:
print(f" {g['title'][:60]} — ${g['price']} — ★{g['rating']}")
Step 3: Scraping Individual Gig Pages
To get detailed gig information including all pricing tiers:
def scrape_gig_details(gig_url):
"""Extract detailed data from a single Fiverr gig page."""
headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
}
response = requests.get(gig_url, headers=headers, timeout=30)
soup = BeautifulSoup(response.text, "html.parser")
details = {}
# Try extracting from embedded JSON first
for script in soup.select('script[id="__NEXT_DATA__"]'):
try:
data = json.loads(script.string)
gig_data = data.get("props", {}).get("pageProps", {}).get("gig", {})
details["title"] = gig_data.get("title")
details["description"] = gig_data.get("description")
details["category"] = gig_data.get("category", {}).get("name")
details["subcategory"] = gig_data.get("sub_category", {}).get("name")
# Pricing tiers
packages = gig_data.get("packages", [])
for pkg in packages:
tier = pkg.get("title", "unknown").lower()
details[f"price_{tier}"] = pkg.get("price")
details[f"delivery_{tier}"] = pkg.get("delivery_time")
details[f"revisions_{tier}"] = pkg.get("revisions")
details[f"description_{tier}"] = pkg.get("description")
# Seller info
seller = gig_data.get("seller", {})
details["seller_username"] = seller.get("username")
details["seller_level"] = seller.get("level")
details["seller_country"] = seller.get("country")
details["seller_response_time"] = seller.get("response_time")
details["seller_member_since"] = seller.get("member_since")
# Stats
details["rating"] = gig_data.get("rating")
details["reviews_count"] = gig_data.get("reviews_count")
details["orders_in_queue"] = gig_data.get("orders_in_queue")
except (json.JSONDecodeError, TypeError):
continue
return details
# Usage
gig = scrape_gig_details("https://www.fiverr.com/someuser/some-gig")
print(json.dumps(gig, indent=2))
Step 4: Scraping Seller Reviews
Reviews are critical for understanding service quality:
def scrape_gig_reviews(gig_url, pages=3):
"""Scrape reviews for a specific Fiverr gig."""
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
"Accept-Language": "en-US,en;q=0.9",
}
all_reviews = []
for page in range(1, pages + 1):
url = f"{gig_url}?page={page}#reviews"
response = requests.get(url, headers=headers, timeout=30)
soup = BeautifulSoup(response.text, "html.parser")
review_items = soup.select('.review-item')
for item in review_items:
review = {}
# Reviewer name and country
name_el = item.select_one('.reviewer-name')
review["reviewer"] = name_el.get_text(strip=True) if name_el else None
country_el = item.select_one('.reviewer-country')
review["country"] = country_el.get_text(strip=True) if country_el else None
# Star rating
stars = item.select('.star-rating .filled')
review["stars"] = len(stars) if stars else None
# Review text
text_el = item.select_one('.review-description')
review["text"] = text_el.get_text(strip=True) if text_el else None
# Date
date_el = item.select_one('.review-date')
review["date"] = date_el.get_text(strip=True) if date_el else None
# Price paid (sometimes visible)
price_el = item.select_one('.review-price')
review["price_paid"] = price_el.get_text(strip=True) if price_el else None
if review["text"]:
all_reviews.append(review)
time.sleep(random.uniform(2, 4))
return all_reviews
Step 5: Category Browsing
To map the entire Fiverr marketplace structure:
def scrape_category(category_slug, subcategory_slug=None, pages=2):
"""Browse Fiverr by category to find top gigs."""
if subcategory_slug:
url = f"https://www.fiverr.com/categories/{category_slug}/{subcategory_slug}"
else:
url = f"https://www.fiverr.com/categories/{category_slug}"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
}
response = requests.get(url, headers=headers, timeout=30)
soup = BeautifulSoup(response.text, "html.parser")
# Extract subcategories if on main category page
subcategories = []
for link in soup.select('a[href*="/categories/"]'):
href = link.get("href", "")
text = link.get_text(strip=True)
if text and category_slug in href:
subcategories.append({"name": text, "url": href})
return {
"subcategories": subcategories,
"url": url,
}
# Example: browse programming category
cats = scrape_category("programming-tech", "web-scraping")
Handling Anti-Bot Protection
Fiverr uses Cloudflare and custom anti-bot measures. Here's what you'll face:
- Cloudflare challenges — JavaScript challenges that block simple HTTP requests
- Rate limiting — aggressive throttling after repeated requests
- Browser fingerprinting — detection of automated browsers
For scraping at scale, you'll need a scraping API that handles these challenges. ScraperAPI manages proxy rotation, CAPTCHA solving, and browser rendering automatically:
SCRAPER_API_KEY = "your_api_key"
def scrape_with_api(url):
"""Use ScraperAPI to handle anti-bot protection."""
api_url = f"http://api.scraperapi.com?api_key={SCRAPER_API_KEY}&url={url}&render=true"
response = requests.get(api_url, timeout=60)
if response.status_code == 200:
return BeautifulSoup(response.text, "html.parser")
else:
print(f"ScraperAPI error: {response.status_code}")
return None
# Use it in place of direct requests
soup = scrape_with_api("https://www.fiverr.com/search/gigs?query=data+scraping")
This is significantly easier than managing your own proxy infrastructure, especially for Cloudflare-protected sites like Fiverr.
Building a Market Research Dataset
Here's how to combine everything into a market research pipeline:
def build_market_dataset(queries, output_file="fiverr_market_data.csv"):
"""Build a dataset of gig listings across multiple search terms."""
all_gigs = []
for query in queries:
print(f"\nSearching for: {query}")
gigs = scrape_fiverr_search(query, pages=2)
for gig in gigs:
gig["search_query"] = query
all_gigs.append(gig)
time.sleep(random.uniform(5, 10))
# Save to CSV
if all_gigs:
keys = all_gigs[0].keys()
with open(output_file, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=keys)
writer.writeheader()
writer.writerows(all_gigs)
print(f"\nSaved {len(all_gigs)} gigs to {output_file}")
return all_gigs
# Research the web scraping niche
queries = [
"web+scraping",
"data+scraping",
"web+crawler",
"scraping+bot",
"api+scraping",
]
dataset = build_market_dataset(queries)
Practical Use Cases
What can you actually do with Fiverr data?
- Pricing research — understand market rates for any service category
- Competitor analysis — see how top sellers position their gigs
- Trend monitoring — track which services are growing in demand
- Quality assessment — analyze review patterns to find reliable sellers
- Niche discovery — find underserved categories with high demand
Limitations and Honest Assessment
-
Cloudflare is tough. Plain
requestswill get blocked quickly. You need either a scraping API or Playwright with stealth plugins. -
Fiverr's frontend changes often. The
__NEXT_DATA__JSON structure can change between deployments. Build your parser to handle missing fields gracefully. - No official API for this data. Fiverr's API is only for sellers managing their own gigs. There's no public API for browsing the marketplace.
- Rate limit strictly. Fiverr will ban your IP fast if you're aggressive. Keep delays between requests at 3+ seconds minimum.
- Respect the platform. Don't scrape personal data, don't spam sellers, and don't use the data for anything that violates Fiverr's Terms of Service.
Pre-Built Solutions
If you'd rather skip the scraping infrastructure entirely, there are pre-built Fiverr scrapers available on platforms like Apify. These handle anti-bot protection, proxy rotation, and data formatting out of the box — just configure your search parameters and get structured JSON output.
Wrapping Up
Fiverr scraping is a great way to understand the freelance marketplace at scale. The combination of __NEXT_DATA__ JSON extraction and a scraping API like ScraperAPI for anti-bot handling gives you a reliable pipeline.
Start small with a single search query, verify your selectors work, then scale up gradually. The freelance economy generates fascinating data — pricing trends, demand shifts, and service quality patterns that aren't visible from casual browsing.
Got questions about scraping other freelance platforms? Drop a comment below.
Top comments (0)