Unofficial Python client for Tweakers.net Pricewatch — search products, browse categories, compare shop prices, and track price history.
Project description
tweakers-pricewatch
Unofficial Python client for Tweakers.net Pricewatch — the biggest price comparison site in the Netherlands.
Lets you search products, browse categories, pull current shop prices, and grab full price history (years of daily min/avg data). All from reverse-engineered endpoints, no API key needed.
Install
Just requests as a dependency. Copy tweakers.py + categories.json into your project, or:
pip install requests
Quick start
from tweakers import TweakersClient
client = TweakersClient()
Search for a product
results = client.search("DDR5 6000")
for r in results:
print(f"[{r.product_id}] {r.name} — {r.url}")
Or grab just the first match:
r = client.search_one("F4-3600C16D-32GTZN")
if r:
print(f"{r.name} [{r.product_id}]")
Browse a category
List all products in a category with pagination and sorting — 40 items per page:
page = client.browse_category("smartphones", sort="prijs", sort_dir="asc")
print(f"{page.total_count} products, page {page.page}/{page.total_pages}")
for item in page.items[:5]:
print(f" {item.name} — EUR {item.price} ({item.shop_count} shops)")
Auto-paginate through all results with browse_all():
for item in client.browse_all("interne-ssds"):
print(f"{item.name}: EUR {item.price}")
Limit to the first N pages:
for item in client.browse_all("videokaarten", max_pages=3):
print(f"{item.name}: EUR {item.price}")
Sort by "prijs" (price), "popularity", or "score" (rating). See CATEGORIES.md for all 243 available category slugs.
Look up categories
from tweakers import get_categories, category_id
cats = get_categories() # {slug: {id, name}, ...}
cid = category_id("videokaarten") # -> 49
Price history
Daily min and average prices going back years:
history = client.get_price_history(2064068)
print(f"{len(history.prices)} days of data")
print(f"Lowest ever: EUR {history.lowest_ever} ({history.lowest_ever_date})")
print(f"Last known: EUR {history.last_price} ({history.last_price_date})")
for p in history.prices[-5:]:
print(f" {p.date} min=EUR {p.min_price} avg=EUR {p.avg_price}")
Belgium prices too:
history_be = client.get_price_history(2064068, country="be")
Product info
Structured data from JSON-LD:
info = client.get_product_info(2064068)
print(f"{info.brand} {info.name}")
print(f"MPN: {info.mpn}") # ['KF560C30BBEK2-32']
print(f"EAN: {info.gtin}") # ['0740617342994']
print(f"EUR {info.low_price} - {info.high_price} ({info.offer_count} shops)")
Current shop prices
All offers:
offers = client.get_current_prices(2064068)
for o in offers:
print(f" {o.shop_name}: EUR {o.price}")
Or just the cheapest:
cheapest = client.get_cheapest_offer(2064068)
if cheapest:
print(f"EUR {cheapest.price} at {cheapest.shop_name}")
Combo: info + prices in one request
info, offers = client.get_product_details(2064068)
Extract product ID from a URL
pid = TweakersClient.product_id_from_url(
"https://tweakers.net/pricewatch/2064068/kingston-fury-beast-kf560c30bbek2-32.html"
)
# -> 2064068
How it works
No official API exists. This uses reverse-engineered endpoints:
| Endpoint | Auth | Returns |
|---|---|---|
/ajax/zoeken/pricewatch/?keyword=... |
None | Search results (JSON) |
/{category}/vergelijken/?page=... |
Session cookies | Category listing with pagination (HTML) |
/ajax/price_chart/{id}/{country}/ |
None | Full price history (JSON) |
/pricewatch/{id}/ |
Session cookies | Product page with JSON-LD + shop listings (HTML) |
The search and price history endpoints need zero authentication — they just work. Product and category pages need a session cookie which the client obtains automatically on init by following Tweakers' DPG Media consent redirect.
Category IDs are stored in categories.json (243 categories). To refresh:
python scripts/update_categories.py
Limitations
- Search returns ~8 results max (it's the autocomplete/suggest endpoint, not full search — the real search page has reCAPTCHA). Use
browse_category()to list products by category instead. - Category browsing and shop offer parsing use regex on HTML, so they may break if Tweakers redesigns the page
- Price history only covers NL and BE
- Be nice with request frequency — there's no rate limiting implemented, so add your own delays if you're hitting it in a loop
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tweakers_pricewatch-0.1.0.tar.gz.
File metadata
- Download URL: tweakers_pricewatch-0.1.0.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f739feff3d1b29ed3b9ba4d65a5cf9b955bc15693f6ca8d5edf45a9c351ed915
|
|
| MD5 |
7326fed10eb778f3c18e87f1a0eb25d9
|
|
| BLAKE2b-256 |
83f06058d5f284916db4e3bb1ee76a238e18f07c8b835a110096fdf8bcbead5e
|
Provenance
The following attestation bundles were made for tweakers_pricewatch-0.1.0.tar.gz:
Publisher:
publish.yml on hatemosphere/tweakers-pricewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tweakers_pricewatch-0.1.0.tar.gz -
Subject digest:
f739feff3d1b29ed3b9ba4d65a5cf9b955bc15693f6ca8d5edf45a9c351ed915 - Sigstore transparency entry: 980289572
- Sigstore integration time:
-
Permalink:
hatemosphere/tweakers-pricewatch@508d763d37cdf1cd780cacbb4ff09d05e51f8d97 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hatemosphere
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@508d763d37cdf1cd780cacbb4ff09d05e51f8d97 -
Trigger Event:
push
-
Statement type:
File details
Details for the file tweakers_pricewatch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tweakers_pricewatch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e93805cde26ecef0681a9a0f97ff77bc6e67bfd338b99b247ea17e83b150226
|
|
| MD5 |
95fbf233173aa6354b251819868964f6
|
|
| BLAKE2b-256 |
2277f1d146c36c83f11598cad1e470bb327d97b0377d146cc866099a5b87169d
|
Provenance
The following attestation bundles were made for tweakers_pricewatch-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on hatemosphere/tweakers-pricewatch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tweakers_pricewatch-0.1.0-py3-none-any.whl -
Subject digest:
0e93805cde26ecef0681a9a0f97ff77bc6e67bfd338b99b247ea17e83b150226 - Sigstore transparency entry: 980289666
- Sigstore integration time:
-
Permalink:
hatemosphere/tweakers-pricewatch@508d763d37cdf1cd780cacbb4ff09d05e51f8d97 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hatemosphere
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@508d763d37cdf1cd780cacbb4ff09d05e51f8d97 -
Trigger Event:
push
-
Statement type: