Skip to content

Commit 8249f55

Browse files
committed
Add get_price_history() documentation to README
1 parent 3b2b250 commit 8249f55

5 files changed

Lines changed: 68 additions & 7 deletions

File tree

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,34 @@ for listing in f.poll_new_listings(
243243

244244
This bypasses ES search and queries the detail API directly, catching listings that haven't been indexed yet.
245245

246+
#### get_price_history(listing)
247+
248+
Get historical price data for a listing, including previous asking prices, WOZ tax assessments, and sale history.
249+
250+
```python
251+
listing = f.get_listing(43032486)
252+
history = f.get_price_history(listing)
253+
254+
for change in history:
255+
print(change['date'], change['human_price'], change['status'])
256+
# 22 okt, 2025 €435.000 asking_price
257+
# 1 jan, 2025 €472.000 woz
258+
# 19 aug, 2019 €300.000 asking_price
259+
```
260+
261+
**Returns:** List of price changes, each containing:
262+
263+
| Field | Description |
264+
|-------|-------------|
265+
| `price` | Numeric price |
266+
| `human_price` | Formatted price (e.g., "€435.000") |
267+
| `date` | Human readable date |
268+
| `timestamp` | ISO timestamp |
269+
| `source` | "Funda" or "WOZ" |
270+
| `status` | `asking_price`, `sold`, or `woz` |
271+
272+
> **Note:** This fetches data from the Walter Living API. Only called when explicitly requested (lazy-loaded).
273+
246274
### Listing
247275

248276
Listing objects support dict-like access with convenient aliases.
@@ -494,6 +522,41 @@ for listing in f.poll_new_listings(since_id=latest_id, offering_type="buy"):
494522

495523
The generator stops after 20 consecutive 404s (configurable via `max_consecutive_404s`).
496524

525+
### Get price history for a listing
526+
527+
```python
528+
from funda import Funda
529+
530+
f = Funda()
531+
listing = f.get_listing(43032486)
532+
533+
# Fetch historical prices (WOZ assessments, previous asking prices, sales)
534+
history = f.get_price_history(listing)
535+
536+
print(f"Price history for {listing['title']}:")
537+
for change in history:
538+
print(f" {change['date']}: {change['human_price']} ({change['status']})")
539+
540+
# Calculate price change over time
541+
funda_prices = [c for c in history if c['source'] == 'Funda']
542+
if len(funda_prices) >= 2:
543+
newest, oldest = funda_prices[0]['price'], funda_prices[-1]['price']
544+
change_pct = ((newest - oldest) / oldest) * 100
545+
print(f"\nPrice change: {change_pct:+.1f}%")
546+
```
547+
548+
## Disclaimer
549+
550+
This is an unofficial library and is not affiliated with, authorized, maintained, sponsored, or endorsed by Funda or any of its affiliates. Use at your own risk.
551+
552+
This library only accesses publicly available listing data through Funda's undocumented internal API. Using this library may violate Funda's Terms of Service. The authors are not responsible for any consequences of using this software.
553+
554+
This project is intended for personal use, research, and educational purposes only.
555+
556+
- The API is undocumented and may change or break at any time without notice.
557+
- Please use this library responsibly and avoid excessive requests that could burden Funda's infrastructure.
558+
- Scraped data may be subject to copyright and usage restrictions. Ensure your use complies with applicable laws.
559+
497560
## License
498561

499562
AGPL-3.0

funda/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
from funda.funda import Funda, FundaAPI
1717
from funda.listing import Listing
1818

19-
__version__ = "2.1.0"
19+
__version__ = "2.2.0"
2020
__all__ = ["Funda", "FundaAPI", "Listing", "__version__"]

funda/funda.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@
1818

1919
# Headers for mobile API
2020
HEADERS = {
21-
"user-agent": "Dart/3.9 (dart:io)",
2221
"x-funda-app-platform": "android",
2322
"content-type": "application/json",
2423
}
2524

2625
SEARCH_HEADERS = {
27-
"user-agent": "Dart/3.9 (dart:io)",
2826
"content-type": "application/json",
2927
"accept": "application/json",
3028
"referer": "https://www.funda.nl/",
@@ -71,7 +69,7 @@ def __init__(self, timeout: int = 30):
7169
def session(self) -> requests.Session:
7270
"""Lazily create HTTP session."""
7371
if self._session is None:
74-
self._session = requests.Session(impersonate="safari")
72+
self._session = requests.Session(impersonate="chrome")
7573
self._session.headers.update(HEADERS)
7674
return self._session
7775

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "pyfunda"
7-
version = "2.1.0"
7+
version = "2.2.0"
88
description = "Python API for Funda.nl real estate listings"
99
readme = "README.md"
1010
license = "AGPL-3.0-or-later"

test_all_flows.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,8 @@ def test_session_headers():
633633
f = Funda()
634634
session = f.session
635635

636-
assert 'user-agent' in session.headers, "Should have user-agent header"
637-
assert 'Dart' in session.headers['user-agent'], "User-agent should contain 'Dart'"
636+
assert 'x-funda-app-platform' in session.headers, "Should have x-funda-app-platform header"
637+
assert session.headers['x-funda-app-platform'] == 'android', "Platform should be android"
638638

639639
f.close()
640640
print(" Session headers set correctly")

0 commit comments

Comments
 (0)