Compare commits
2 Commits
7d3021efbf
...
0ea31d3013
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ea31d3013 | |||
|
|
4304a42776 |
@@ -79,6 +79,10 @@ def main():
|
|||||||
if key in seen_keys:
|
if key in seen_keys:
|
||||||
dupes += 1
|
dupes += 1
|
||||||
existing = seen_keys[key]
|
existing = seen_keys[key]
|
||||||
|
# Preserve earliest first_seen across sources
|
||||||
|
dup_fs = e.get("first_seen", "")
|
||||||
|
if dup_fs and (not existing.get("first_seen") or dup_fs < existing["first_seen"]):
|
||||||
|
existing["first_seen"] = dup_fs
|
||||||
# Log it
|
# Log it
|
||||||
print(f" Duplikát: {e['locality']} | {format_price(e['price'])} | {e.get('area', '?')} m² "
|
print(f" Duplikát: {e['locality']} | {format_price(e['price'])} | {e.get('area', '?')} m² "
|
||||||
f"({e.get('source', '?')} vs {existing.get('source', '?')})")
|
f"({e.get('source', '?')} vs {existing.get('source', '?')})")
|
||||||
|
|||||||
@@ -353,6 +353,8 @@ def scrape(max_pages: int | None = None, max_properties: int | None = None):
|
|||||||
"url": sreality_url(hash_id, seo),
|
"url": sreality_url(hash_id, seo),
|
||||||
"image": (estate.get("_links", {}).get("images", [{}])[0].get("href", "") if estate.get("_links", {}).get("images") else ""),
|
"image": (estate.get("_links", {}).get("images", [{}])[0].get("href", "") if estate.get("_links", {}).get("images") else ""),
|
||||||
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"first_seen": cached.get("first_seen", datetime.now().strftime("%Y-%m-%d")) if cached else datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"last_changed": datetime.now().strftime("%Y-%m-%d"),
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
details_fetched += 1
|
details_fetched += 1
|
||||||
@@ -429,11 +431,19 @@ def generate_map(estates: list[dict], output_path: str = "mapa_bytu.html"):
|
|||||||
]
|
]
|
||||||
for bcolor, blabel in bands:
|
for bcolor, blabel in bands:
|
||||||
price_legend_items += (
|
price_legend_items += (
|
||||||
f'<div style="display:flex;align-items:center;gap:6px;margin:2px 0;">'
|
f'<div class="price-band" data-color="{bcolor}" onclick="toggleColorFilter(\'{bcolor}\')" '
|
||||||
|
f'style="display:flex;align-items:center;gap:6px;margin:2px 0;padding:2px 4px;'
|
||||||
|
f'border-radius:4px;border:2px solid transparent;">'
|
||||||
f'<span style="width:14px;height:14px;border-radius:50%;background:{bcolor};'
|
f'<span style="width:14px;height:14px;border-radius:50%;background:{bcolor};'
|
||||||
f'display:inline-block;border:2px solid white;box-shadow:0 1px 3px rgba(0,0,0,0.3);flex-shrink:0;"></span>'
|
f'display:inline-block;border:2px solid white;box-shadow:0 1px 3px rgba(0,0,0,0.3);flex-shrink:0;"></span>'
|
||||||
f'<span>{blabel}</span></div>'
|
f'<span>{blabel}</span></div>'
|
||||||
)
|
)
|
||||||
|
price_legend_items += (
|
||||||
|
'<div id="price-filter-reset" style="display:none;margin:3px 0 0 4px;">'
|
||||||
|
'<a href="#" onclick="resetColorFilter();return false;" '
|
||||||
|
'style="font-size:11px;color:#1976D2;text-decoration:none;">✕ Zobrazit všechny ceny</a>'
|
||||||
|
'</div>'
|
||||||
|
)
|
||||||
# New marker indicator — bigger dot, no extra border
|
# New marker indicator — bigger dot, no extra border
|
||||||
price_legend_items += (
|
price_legend_items += (
|
||||||
'<div style="display:flex;align-items:center;gap:6px;margin:6px 0 0 0;'
|
'<div style="display:flex;align-items:center;gap:6px;margin:6px 0 0 0;'
|
||||||
@@ -464,16 +474,28 @@ def generate_map(estates: list[dict], output_path: str = "mapa_bytu.html"):
|
|||||||
|
|
||||||
hash_id = e.get("hash_id", "")
|
hash_id = e.get("hash_id", "")
|
||||||
|
|
||||||
scraped_at = e.get("scraped_at", "")
|
first_seen = e.get("first_seen", "")
|
||||||
is_new = scraped_at == datetime.now().strftime("%Y-%m-%d")
|
last_changed = e.get("last_changed", "")
|
||||||
|
is_new = first_seen == datetime.now().strftime("%Y-%m-%d")
|
||||||
|
|
||||||
new_badge = (
|
new_badge = (
|
||||||
'<span style="margin-left:6px;font-size:11px;background:#FFD600;color:#333;'
|
'<span style="margin-left:6px;font-size:11px;background:#FFD600;color:#333;'
|
||||||
'padding:1px 6px;border-radius:3px;font-weight:bold;">NOVÉ</span>'
|
'padding:1px 6px;border-radius:3px;font-weight:bold;">NOVÉ</span>'
|
||||||
if is_new else ""
|
if is_new else ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
date_parts = []
|
||||||
|
if first_seen:
|
||||||
|
date_parts.append(f'Přidáno: {first_seen}')
|
||||||
|
if last_changed and last_changed != first_seen:
|
||||||
|
date_parts.append(f'Změněno: {last_changed}')
|
||||||
|
date_row = (
|
||||||
|
f'<span style="font-size:11px;color:#888;">{" · ".join(date_parts)}</span><br>'
|
||||||
|
if date_parts else ""
|
||||||
|
)
|
||||||
|
|
||||||
popup = (
|
popup = (
|
||||||
f'<div style="min-width:280px;font-family:system-ui,sans-serif;" data-hashid="{hash_id}">'
|
f'<div style="min-width:280px;font-family:system-ui,sans-serif;" data-hashid="{hash_id}" data-first-seen="{first_seen}" data-last-changed="{last_changed}">'
|
||||||
f'<b style="font-size:14px;">{format_price(e["price"])}</b>'
|
f'<b style="font-size:14px;">{format_price(e["price"])}</b>'
|
||||||
f'<span style="margin-left:8px;font-size:11px;background:{source_color};color:white;'
|
f'<span style="margin-left:8px;font-size:11px;background:{source_color};color:white;'
|
||||||
f'padding:1px 6px;border-radius:3px;">{source_label}</span>{new_badge}<br>'
|
f'padding:1px 6px;border-radius:3px;">{source_label}</span>{new_badge}<br>'
|
||||||
@@ -481,7 +503,9 @@ def generate_map(estates: list[dict], output_path: str = "mapa_bytu.html"):
|
|||||||
f'{floor_note}<br><br>'
|
f'{floor_note}<br><br>'
|
||||||
f'<b>{e["locality"]}</b><br>'
|
f'<b>{e["locality"]}</b><br>'
|
||||||
f'Stavba: {building_text}<br>'
|
f'Stavba: {building_text}<br>'
|
||||||
f'Vlastnictví: {ownership_text}<br><br>'
|
f'Vlastnictví: {ownership_text}<br>'
|
||||||
|
f'{date_row}'
|
||||||
|
f'<br>'
|
||||||
f'<a href="{e["url"]}" target="_blank" '
|
f'<a href="{e["url"]}" target="_blank" '
|
||||||
f'style="color:{source_color};text-decoration:none;font-weight:bold;">'
|
f'style="color:{source_color};text-decoration:none;font-weight:bold;">'
|
||||||
f'→ Otevřít na {source_label}</a>'
|
f'→ Otevřít na {source_label}</a>'
|
||||||
@@ -513,7 +537,7 @@ def generate_map(estates: list[dict], output_path: str = "mapa_bytu.html"):
|
|||||||
else:
|
else:
|
||||||
marker_fn = "addMarker"
|
marker_fn = "addMarker"
|
||||||
markers_js += (
|
markers_js += (
|
||||||
f" {marker_fn}({e['lat']}, {e['lon']}, '{color}', '{popup}', '{hash_id}');\n"
|
f" {marker_fn}({e['lat']}, {e['lon']}, '{color}', '{popup}', '{hash_id}', '{first_seen}', '{last_changed}');\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build legend — price per m² bands + disposition counts
|
# Build legend — price per m² bands + disposition counts
|
||||||
@@ -617,6 +641,10 @@ def generate_map(estates: list[dict], output_path: str = "mapa_bytu.html"):
|
|||||||
.info-panel .stats {{ color: #666; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee; }}
|
.info-panel .stats {{ color: #666; margin-bottom: 10px; padding-bottom: 10px; border-bottom: 1px solid #eee; }}
|
||||||
.filter-section {{ margin-top: 10px; padding-top: 10px; border-top: 1px solid #eee; }}
|
.filter-section {{ margin-top: 10px; padding-top: 10px; border-top: 1px solid #eee; }}
|
||||||
.filter-section label {{ display: flex; align-items: center; gap: 6px; margin: 3px 0; cursor: pointer; }}
|
.filter-section label {{ display: flex; align-items: center; gap: 6px; margin: 3px 0; cursor: pointer; }}
|
||||||
|
.price-band {{ cursor: pointer; transition: background 0.12s; }}
|
||||||
|
.price-band:hover {{ background: #f0f0f0; }}
|
||||||
|
.price-band.active {{ border-color: #333 !important; background: #e8f0fe; }}
|
||||||
|
.price-band.dimmed {{ opacity: 0.35; }}
|
||||||
.filter-section input[type="checkbox"] {{ accent-color: #1976D2; }}
|
.filter-section input[type="checkbox"] {{ accent-color: #1976D2; }}
|
||||||
#floor-filter {{ margin-top: 8px; }}
|
#floor-filter {{ margin-top: 8px; }}
|
||||||
#floor-filter select {{ width: 100%; padding: 4px; border-radius: 4px; border: 1px solid #ccc; }}
|
#floor-filter select {{ width: 100%; padding: 4px; border-radius: 4px; border: 1px solid #ccc; }}
|
||||||
@@ -663,6 +691,21 @@ def generate_map(estates: list[dict], output_path: str = "mapa_bytu.html"):
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="margin-top:6px;">
|
||||||
|
<label>Přidáno / změněno:
|
||||||
|
<select id="days-filter" onchange="applyFilters()" style="width:100%;padding:4px;border-radius:4px;border:1px solid #ccc;">
|
||||||
|
<option value="0">Vše</option>
|
||||||
|
<option value="1">za 1 den</option>
|
||||||
|
<option value="2">za 2 dny</option>
|
||||||
|
<option value="3">za 3 dny</option>
|
||||||
|
<option value="4">za 4 dny</option>
|
||||||
|
<option value="5">za 5 dní</option>
|
||||||
|
<option value="7">za 7 dní</option>
|
||||||
|
<option value="14">za 14 dní</option>
|
||||||
|
<option value="30">za 30 dní</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="filter-section">
|
<div class="filter-section">
|
||||||
<div id="rating-counts" style="margin-bottom:6px;font-size:12px;color:#666;">
|
<div id="rating-counts" style="margin-bottom:6px;font-size:12px;color:#666;">
|
||||||
@@ -693,9 +736,39 @@ L.tileLayer('https://{{s}}.basemaps.cartocdn.com/light_only_labels/{{z}}/{{x}}/{
|
|||||||
pane: 'shadowPane',
|
pane: 'shadowPane',
|
||||||
}}).addTo(map);
|
}}).addTo(map);
|
||||||
|
|
||||||
|
var selectedColors = [];
|
||||||
|
|
||||||
|
function toggleColorFilter(color) {{
|
||||||
|
var idx = selectedColors.indexOf(color);
|
||||||
|
if (idx >= 0) selectedColors.splice(idx, 1);
|
||||||
|
else selectedColors.push(color);
|
||||||
|
document.querySelectorAll('.price-band').forEach(function(el) {{
|
||||||
|
var c = el.getAttribute('data-color');
|
||||||
|
if (selectedColors.length === 0) {{
|
||||||
|
el.classList.remove('active', 'dimmed');
|
||||||
|
}} else if (selectedColors.indexOf(c) >= 0) {{
|
||||||
|
el.classList.add('active'); el.classList.remove('dimmed');
|
||||||
|
}} else {{
|
||||||
|
el.classList.add('dimmed'); el.classList.remove('active');
|
||||||
|
}}
|
||||||
|
}});
|
||||||
|
document.getElementById('price-filter-reset').style.display =
|
||||||
|
selectedColors.length > 0 ? 'block' : 'none';
|
||||||
|
applyFilters();
|
||||||
|
}}
|
||||||
|
|
||||||
|
function resetColorFilter() {{
|
||||||
|
selectedColors = [];
|
||||||
|
document.querySelectorAll('.price-band').forEach(function(el) {{
|
||||||
|
el.classList.remove('active', 'dimmed');
|
||||||
|
}});
|
||||||
|
document.getElementById('price-filter-reset').style.display = 'none';
|
||||||
|
applyFilters();
|
||||||
|
}}
|
||||||
|
|
||||||
var allMarkers = [];
|
var allMarkers = [];
|
||||||
|
|
||||||
function addMarker(lat, lon, color, popup, hashId) {{
|
function addMarker(lat, lon, color, popup, hashId, firstSeen, lastChanged) {{
|
||||||
var marker = L.circleMarker([lat, lon], {{
|
var marker = L.circleMarker([lat, lon], {{
|
||||||
radius: 8,
|
radius: 8,
|
||||||
fillColor: color,
|
fillColor: color,
|
||||||
@@ -704,12 +777,12 @@ function addMarker(lat, lon, color, popup, hashId) {{
|
|||||||
opacity: 1,
|
opacity: 1,
|
||||||
fillOpacity: 0.85,
|
fillOpacity: 0.85,
|
||||||
}}).bindPopup(popup);
|
}}).bindPopup(popup);
|
||||||
marker._data = {{ lat: lat, lon: lon, color: color, hashId: hashId }};
|
marker._data = {{ lat: lat, lon: lon, color: color, hashId: hashId, firstSeen: firstSeen || '', lastChanged: lastChanged || '' }};
|
||||||
allMarkers.push(marker);
|
allMarkers.push(marker);
|
||||||
marker.addTo(map);
|
marker.addTo(map);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
function addNewMarker(lat, lon, color, popup, hashId) {{
|
function addNewMarker(lat, lon, color, popup, hashId, firstSeen, lastChanged) {{
|
||||||
var marker = L.circleMarker([lat, lon], {{
|
var marker = L.circleMarker([lat, lon], {{
|
||||||
radius: 12,
|
radius: 12,
|
||||||
fillColor: color,
|
fillColor: color,
|
||||||
@@ -718,7 +791,7 @@ function addNewMarker(lat, lon, color, popup, hashId) {{
|
|||||||
opacity: 0.35,
|
opacity: 0.35,
|
||||||
fillOpacity: 0.95,
|
fillOpacity: 0.95,
|
||||||
}}).bindPopup(popup);
|
}}).bindPopup(popup);
|
||||||
marker._data = {{ lat: lat, lon: lon, color: color, hashId: hashId, isNew: true }};
|
marker._data = {{ lat: lat, lon: lon, color: color, hashId: hashId, isNew: true, firstSeen: firstSeen || '', lastChanged: lastChanged || '' }};
|
||||||
allMarkers.push(marker);
|
allMarkers.push(marker);
|
||||||
marker.addTo(map);
|
marker.addTo(map);
|
||||||
marker.on('add', function() {{
|
marker.on('add', function() {{
|
||||||
@@ -756,11 +829,11 @@ function starIcon() {{
|
|||||||
}});
|
}});
|
||||||
}}
|
}}
|
||||||
|
|
||||||
function addHeartMarker(lat, lon, color, popup, hashId) {{
|
function addHeartMarker(lat, lon, color, popup, hashId, firstSeen, lastChanged) {{
|
||||||
var marker = L.marker([lat, lon], {{
|
var marker = L.marker([lat, lon], {{
|
||||||
icon: heartIcon(color),
|
icon: heartIcon(color),
|
||||||
}}).bindPopup(popup);
|
}}).bindPopup(popup);
|
||||||
marker._data = {{ lat: lat, lon: lon, color: color, hashId: hashId, isHeart: true }};
|
marker._data = {{ lat: lat, lon: lon, color: color, hashId: hashId, isHeart: true, firstSeen: firstSeen || '', lastChanged: lastChanged || '' }};
|
||||||
allMarkers.push(marker);
|
allMarkers.push(marker);
|
||||||
marker.addTo(map);
|
marker.addTo(map);
|
||||||
}}
|
}}
|
||||||
@@ -1018,9 +1091,17 @@ function applyFilters() {{
|
|||||||
var minFloor = parseInt(document.getElementById('min-floor').value);
|
var minFloor = parseInt(document.getElementById('min-floor').value);
|
||||||
var maxPrice = parseInt(document.getElementById('max-price').value);
|
var maxPrice = parseInt(document.getElementById('max-price').value);
|
||||||
var hideRejected = document.getElementById('hide-rejected').checked;
|
var hideRejected = document.getElementById('hide-rejected').checked;
|
||||||
|
var daysFilter = parseInt(document.getElementById('days-filter').value) || 0;
|
||||||
var ratings = loadRatings();
|
var ratings = loadRatings();
|
||||||
var visible = 0;
|
var visible = 0;
|
||||||
|
|
||||||
|
var cutoff = null;
|
||||||
|
if (daysFilter > 0) {{
|
||||||
|
cutoff = new Date();
|
||||||
|
cutoff.setDate(cutoff.getDate() - daysFilter);
|
||||||
|
cutoff.setHours(0, 0, 0, 0);
|
||||||
|
}}
|
||||||
|
|
||||||
allMarkers.forEach(function(m) {{
|
allMarkers.forEach(function(m) {{
|
||||||
var popup = m.getPopup().getContent();
|
var popup = m.getPopup().getContent();
|
||||||
var floorMatch = popup.match(/(\\d+)\\. NP/);
|
var floorMatch = popup.match(/(\\d+)\\. NP/);
|
||||||
@@ -1033,6 +1114,14 @@ function applyFilters() {{
|
|||||||
if (floor !== null && floor < minFloor) show = false;
|
if (floor !== null && floor < minFloor) show = false;
|
||||||
if (price > maxPrice) show = false;
|
if (price > maxPrice) show = false;
|
||||||
|
|
||||||
|
if (cutoff) {{
|
||||||
|
var fs = m._data.firstSeen ? new Date(m._data.firstSeen) : null;
|
||||||
|
var lc = m._data.lastChanged ? new Date(m._data.lastChanged) : null;
|
||||||
|
if (!((fs && fs >= cutoff) || (lc && lc >= cutoff))) show = false;
|
||||||
|
}}
|
||||||
|
|
||||||
|
if (selectedColors.length > 0 && selectedColors.indexOf(m._data.color) < 0) show = false;
|
||||||
|
|
||||||
var r = ratings[m._data.hashId];
|
var r = ratings[m._data.hashId];
|
||||||
if (hideRejected && r && r.status === 'reject') show = false;
|
if (hideRejected && r && r.status === 'reject') show = false;
|
||||||
|
|
||||||
|
|||||||
@@ -362,6 +362,8 @@ def scrape(max_pages: int | None = None, max_properties: int | None = None):
|
|||||||
"source": "bezrealitky",
|
"source": "bezrealitky",
|
||||||
"image": "",
|
"image": "",
|
||||||
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"first_seen": cached.get("first_seen", datetime.now().strftime("%Y-%m-%d")) if cached else datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"last_changed": datetime.now().strftime("%Y-%m-%d"),
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
properties_fetched += 1
|
properties_fetched += 1
|
||||||
|
|||||||
@@ -255,6 +255,16 @@ def scrape(max_pages: int | None = None, max_properties: int | None = None):
|
|||||||
else:
|
else:
|
||||||
logger.info(f"✗ {slug}: GPS nenalezeno")
|
logger.info(f"✗ {slug}: GPS nenalezeno")
|
||||||
|
|
||||||
|
# Load previous output for first_seen/last_changed tracking
|
||||||
|
_prev_cache: dict[str, dict] = {}
|
||||||
|
_prev_path = Path("byty_cityhome.json")
|
||||||
|
if _prev_path.exists():
|
||||||
|
try:
|
||||||
|
for _item in json.loads(_prev_path.read_text(encoding="utf-8")):
|
||||||
|
_prev_cache[str(_item["hash_id"])] = _item
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
# Step 3: Filter listings
|
# Step 3: Filter listings
|
||||||
logger.info(f"\nFáze 3: Filtrování...")
|
logger.info(f"\nFáze 3: Filtrování...")
|
||||||
results = []
|
results = []
|
||||||
@@ -362,6 +372,8 @@ def scrape(max_pages: int | None = None, max_properties: int | None = None):
|
|||||||
"source": "cityhome",
|
"source": "cityhome",
|
||||||
"image": "",
|
"image": "",
|
||||||
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"first_seen": _prev_cache.get(f"cityhome_{slug}_{listing['unit_name']}", {}).get("first_seen", datetime.now().strftime("%Y-%m-%d")),
|
||||||
|
"last_changed": datetime.now().strftime("%Y-%m-%d") if _prev_cache.get(f"cityhome_{slug}_{listing['unit_name']}", {}).get("price") != price else _prev_cache[f"cityhome_{slug}_{listing['unit_name']}"].get("last_changed", datetime.now().strftime("%Y-%m-%d")),
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
properties_fetched += 1
|
properties_fetched += 1
|
||||||
|
|||||||
@@ -465,6 +465,8 @@ def scrape(max_pages: int | None = None, max_properties: int | None = None):
|
|||||||
"source": "idnes",
|
"source": "idnes",
|
||||||
"image": "",
|
"image": "",
|
||||||
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"first_seen": cached.get("first_seen", datetime.now().strftime("%Y-%m-%d")) if cached else datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"last_changed": datetime.now().strftime("%Y-%m-%d"),
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
properties_fetched += 1
|
properties_fetched += 1
|
||||||
|
|||||||
@@ -112,6 +112,16 @@ def scrape(max_properties: int | None = None):
|
|||||||
all_units = data.get("units", {}).get("data", [])
|
all_units = data.get("units", {}).get("data", [])
|
||||||
logger.info(f"Staženo jednotek celkem: {len(all_units)}")
|
logger.info(f"Staženo jednotek celkem: {len(all_units)}")
|
||||||
|
|
||||||
|
# Load previous output for first_seen/last_changed tracking
|
||||||
|
_prev_cache: dict[str, dict] = {}
|
||||||
|
_prev_path = Path("byty_psn.json")
|
||||||
|
if _prev_path.exists():
|
||||||
|
try:
|
||||||
|
for _item in json.loads(_prev_path.read_text(encoding="utf-8")):
|
||||||
|
_prev_cache[str(_item["hash_id"])] = _item
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
# Filtrování
|
# Filtrování
|
||||||
results = []
|
results = []
|
||||||
excluded = {
|
excluded = {
|
||||||
@@ -242,6 +252,8 @@ def scrape(max_properties: int | None = None):
|
|||||||
"source": "psn",
|
"source": "psn",
|
||||||
"image": "",
|
"image": "",
|
||||||
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"first_seen": _prev_cache.get(str(unit_id), {}).get("first_seen", datetime.now().strftime("%Y-%m-%d")),
|
||||||
|
"last_changed": datetime.now().strftime("%Y-%m-%d") if _prev_cache.get(str(unit_id), {}).get("price") != int(price) else _prev_cache[str(unit_id)].get("last_changed", datetime.now().strftime("%Y-%m-%d")),
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
properties_fetched += 1
|
properties_fetched += 1
|
||||||
|
|||||||
@@ -321,6 +321,8 @@ def scrape(max_pages: int | None = None, max_properties: int | None = None):
|
|||||||
"source": "realingo",
|
"source": "realingo",
|
||||||
"image": "",
|
"image": "",
|
||||||
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
"scraped_at": datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"first_seen": cached.get("first_seen", datetime.now().strftime("%Y-%m-%d")) if cached else datetime.now().strftime("%Y-%m-%d"),
|
||||||
|
"last_changed": datetime.now().strftime("%Y-%m-%d"),
|
||||||
}
|
}
|
||||||
results.append(result)
|
results.append(result)
|
||||||
properties_fetched += 1
|
properties_fetched += 1
|
||||||
|
|||||||
Reference in New Issue
Block a user