Hepsiburada Products Scraper
Pricing
from $1.05 / 1,000 results
Hepsiburada Products Scraper
Product listings from Hepsiburada, Turkey's second-largest marketplace: price in lira, instalment offer, rating, reviews and badges. The price is read from its own node -- the first number on a card is the instalment, and a naive read reports a 32,999 TL laptop at 5,499.
Pricing
from $1.05 / 1,000 results
Rating
0.0
(0)
Developer
Ibnu Adzim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Product listings from Hepsiburada, Turkey's second-largest marketplace: price in lira, the instalment offer, rating and review count, badges, image and product URL — for any search term.
HTTP only, no browser, no key. Off Hepsiburada's own server-rendered listing.
Input
| field | what it does |
|---|---|
searchTerms | laptop, kulaklık, iphone 15 — one target per term. |
maxItems | Overall cap. One term tops out at ~1,800 (see below). |
maxConcurrency, minRequestInterval | Pacing. Pages are 3.5 MB each. |
Four things about this data worth knowing
1. The first price on the card is the instalment, not the price
A card's text, in the order it appears, for a 32,999 TL laptop:
'Lenovo IdeaPad Slim 3 …', 'Ürün puanı 4.9, 23 değerlendirme', '4,9','Kampanya: Peşin fiyatına 6 x 5.499 TL', '6 x', '5.499 TL', ← first "N TL"'32.999', 'TL' ← the price
"Peşin fiyatına 6 x 5.499 TL" is six instalments at the cash price. A
scraper that takes the first string containing "TL" reports 5,499 TL for a
32,999 TL laptop — wrong by about 6×, and nothing about 5,499 looks wrong
for a laptop. This Actor reads the price from its own node only, and keeps the
instalment beside it as installmentCount × installmentAmount.
2. Two id spaces on one page
…-83k700pstr-p-HBCV0000FC0KHB a SKU (one specific variant)…-bilgisayar-pm-HBC0000D9H7T8 a MODEL (a product with variants)
Half the cards on a page are one, half the other. A parser keyed on -p-
alone returns null ids for the model half, and a run that de-duplicates on
that id then collapses them all into one row. Both are read; every row carries
idType, and the summary counts skuRows and modelRows so a regression in
either is visible.
3. Turkish numbers, with the decimals in a separate node
68.238 + ,40 + TL is 68,238.40 lira: . is the thousands separator,
, the decimal mark, and the ,40 lives in a nested node whose text is just
TL when there are no decimals. float("68.238") is wrong by 1000× and still
looks like a plausible price for something. Every row keeps priceRaw so the
arithmetic is auditable.
4. Page 50 answers HTTP 403 — and it is not a block
Page 49 returns 36 cards. Page 50 returns 403 with a 1,753-byte body; so do
pages 500 and 9999, while page 1 keeps answering 200 in the same session. It is
Hepsiburada's way of saying "no such page", but it reads exactly like a WAF
kicking in mid-crawl. The wall is pinned at 49 and never requested — roughly
1,800 products per term — and reaching it is reported as ceilingHit.
Output
PRODUCT—productId+idType,title,price+priceRaw+currency,installmentCount+installmentAmount+campaignText,rating,reviewCount,badges,imageUrl,productUrl.SEARCH_SUMMARY—productsReturned,matchCountAvailable: false,skuRows,modelRows,rowsWithoutId,duplicateRowsDropped,ceilingHit,stoppedReason.ERROR— one row naming what went wrong, instead of a silent empty.
Technical notes
- Every class name carries a build hash (
price-module_finalPrice__LtjvY) that changes on deploy. Every selector matches on the stable stem with[class*=…], never on a full class name. - One search in a handful comes back as HTTP 206 with the complete page. A 200-only classifier files that as fatal and loses the term; 2xx is treated as success here and the card count decides.
- Two kinds of empty page. A nonsense term returns zero cards with a
"bulunamadı" marker — an honest no-results. An empty term returns zero cards
without it — the search page with nothing searched. The empty term is
refused locally; zero cards without the marker is reported as
page_shape_changedrather than as "no results". - No keyword-match check, deliberately. Titles are Turkish ("Taşınabilir Bilgisayar"), queries often English ("laptop"), and the failure such a check guards against elsewhere — a dropped keyword answered with an unrelated catalogue — was measured not to exist here. A check with no true-positive case and a routine false-positive case is worse than none.
- robots.txt checked 2026-09-16: no AI-bot group, no blanket disallow,
/ara?q=allowed. The platform inventory was checked before a line was written.
Known limits
- The listing carries no struck-through price, no merchant name and no result total — checked on a discount-sorted search too. Product detail pages are not read.
- ~1,800 products per search term. Slice with narrower terms to go wider.
- Prices in lira only.