A working guide to building an eBay scraper with the ScrapingBee web scraping API. eBay loads listings with JavaScript and blocks automated traffic quickly, so a plain HTTP request returns a partial or challenge page. This repo shows how an eBay scraper API renders the page, rotates residential proxies, and returns clean product data from a single call, using the CSS selectors from ScrapingBee's own eBay guide.
curl "https://app.scrapingbee.com/api/v1/?api_key=YOUR_API_KEY&url=https%3A%2F%2Fwww.ebay.com%2Fsch%2Fi.html%3F_nkw%3Dnintendo%2520switch&render_js=true&premium_proxy=true&country_code=us&wait=5000"You need a ScrapingBee API key. The free tier gives you 1,000 credits with no card required: scrapingbee.com.
eBay is a live market of prices, conditions, sellers, and sold history. That data drives reselling and arbitrage, price monitoring, product research, and competitor tracking. eBay does not offer an open data API for this, so an eBay web scraper is the practical way to collect it at scale.
The hard parts are the same as any large marketplace: listings render with JavaScript, datacenter IPs get rate-limited or served a challenge, and the markup changes. A managed eBay scraper API handles rendering, proxy rotation, and structured extraction so you send one request and read the result.
import requests
from bs4 import BeautifulSoup
url = "https://www.ebay.com/sch/i.html?_nkw=nintendo switch"
html = requests.get(url).text
soup = BeautifulSoup(html, "html.parser")
# Often returns a partial page or a challenge, because eBay renders results
# with JavaScript and flags the default python-requests client.
print([c.get_text(strip=True) for c in soup.select("li.s-card")][:5])This is the wall the ScrapingBee eBay guide addresses with JavaScript rendering and premium proxies.
Four parameters do the work for eBay, straight from the guide: render_js for the dynamic content, premium_proxy so the request is not blocked, country_code for the eBay region, and wait for the results to load. Around 5000ms works well for eBay.
curl "https://app.scrapingbee.com/api/v1/?api_key=YOUR_API_KEY&url=https%3A%2F%2Fwww.ebay.com%2Fsch%2Fi.html%3F_nkw%3Dnintendo%2520switch&render_js=true&premium_proxy=true&country_code=us&wait=5000"pip install scrapingbeefrom scrapingbee import ScrapingBeeClient
client = ScrapingBeeClient(api_key="YOUR_API_KEY")
response = client.get(
"https://www.ebay.com/sch/i.html?_nkw=nintendo switch",
params={
"render_js": "true",
"premium_proxy": "true",
"country_code": "us",
"wait": "5000",
},
)
print(response.content)const axios = require('axios');
axios.get('https://app.scrapingbee.com/api/v1/', {
params: {
api_key: 'YOUR_API_KEY',
url: 'https://www.ebay.com/sch/i.html?_nkw=nintendo switch',
render_js: 'true',
premium_proxy: 'true',
country_code: 'us',
wait: 5000,
},
}).then((response) => console.log(response.data));Instead of parsing HTML yourself, pass extract_rules and get JSON back. These selectors come from ScrapingBee's eBay guide, so they target the current search-results markup.
extract_rules = {
"products": {
"selector": "li.s-card",
"type": "list",
"output": {
"title": "div.s-card__title span.su-styled-text",
"price": "span.s-card__price",
"url": {"selector": "a.s-card__link:not(.image-treatment)", "output": "@href"},
"shipping": "div.s-card__attribute-row",
},
}
}
response = client.get(
"https://www.ebay.com/sch/i.html?_nkw=nintendo switch",
params={
"render_js": "true",
"premium_proxy": "true",
"country_code": "us",
"wait": "5000",
"extract_rules": extract_rules,
},
)
print(response.json())CSS extraction does not add credits. If eBay changes its class names, update the selectors, or switch to ai_extract_rules for natural-language extraction, which adds 5 credits.
eBay's search URL carries the state you need:
- Search:
https://www.ebay.com/sch/i.html?_nkw=QUERY - Page N: add
&_pgn=2 - Sold and completed: add
&LH_Complete=1&LH_Sold=1, which turns an eBay product scraper into a price-history tool
Loop the page number and keep the same parameters to walk every result page.
| Parameter | Value for eBay | Description |
|---|---|---|
api_key |
required | Your ScrapingBee API key |
url |
required | eBay search or listing URL (URL-encode for raw cURL) |
render_js |
true |
Execute eBay's JavaScript |
premium_proxy |
true |
Residential proxies, so eBay does not block the request |
country_code |
us |
eBay region |
wait |
5000 |
Milliseconds to wait for results to load |
extract_rules |
JSON | CSS or XPath extraction, returns JSON, no extra credits |
ai_extract_rules |
JSON | Natural-language extraction, adds 5 credits |
ScrapingBee bills successful requests. An eBay request with render_js and premium_proxy costs 25 credits. CSS extract_rules adds nothing. ai_extract_rules or ai_query adds 5. Current rate card: ScrapingBee pricing.
- Price monitoring across sellers for a product you track.
- Reselling and arbitrage, using sold listings for real sale prices.
- Product research on demand, condition mix, and shipping.
- Competitor tracking of a rival store's active listings.
- Keep
render_js=true; eBay's results are dynamic. - Use
premium_proxy=trueso requests are not rate-limited. - Give the page time with
wait=5000before extraction. - Prefer
extract_rulesover hand-parsing, and update selectors when eBay changes markup. - Scrape public eBay pages only. ScrapingBee's terms prohibit scraping behind a login.
eBay's developer APIs are limited and gated. For open collection of public search and listing data, an eBay data scraper that renders the page is the practical route, which is what this approach does.
eBay renders listings with JavaScript and flags the default request client. You need JavaScript rendering and residential proxies, which the API provides through render_js and premium_proxy.
Pass extract_rules with CSS selectors for the fields you want, or ai_extract_rules for natural-language extraction. Both return JSON.
Yes. Add &LH_Complete=1&LH_Sold=1 to the eBay search URL to filter to completed and sold listings.
- How to scrape eBay (ScrapingBee)
- ScrapingBee documentation
- Data extraction rules
- ScrapingBee pricing
MIT