MacOS_Parsers/Парсер_IKEA/category_scrap.py

93 lines
3.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# ikea_leaf_categories.py • собирает «листовые» категории каталога
import json, requests, pathlib, pandas as pd, time, sys
# ── настройки ────────────────────────────────────────────────────
BASE_DIR = pathlib.Path(__file__).resolve().parent
LOCALE_PATH = "/pl/pl/" # ← поменяйте на /de/de/, /fr/fr/ … при нужде
JSON_URL = (f"https://www.ikea.com{LOCALE_PATH}"
"meta-data/navigation/catalog-products-slim.json")
HEADERS = {"User-Agent": "Mozilla/5.0", "Accept": "application/json"}
TXT_OUT = BASE_DIR / "leaf_categories.txt"
XLSX_OUT = BASE_DIR / "leaf_categories.xlsx"
EXCLUDE_NAMES = {"Wyprzedaż"} # можно расширять
EXCLUDE_URL_SNIPPETS = {"/last-chance/"} # подстроки url, которые нужно отсечь
# ── загрузка JSON ────────────────────────────────────────────────
def fetch_json():
r = requests.get(JSON_URL, headers=HEADERS, timeout=10)
r.raise_for_status()
return r.json()
# ── рекурсивный обход ────────────────────────────────────────────
def walk(node: dict, acc: list):
# ── NEW: фильтр «Wyprzedaż / last-chance» ─────────────────────
nm = node.get("name", "")
url = node.get("url", "")
if nm in EXCLUDE_NAMES or any(sn in url for sn in EXCLUDE_URL_SNIPPETS):
return # просто не лезем в эту ветку
# ─────────────────────────────────────────────────────────────
subs = node.get("subs") or []
if not subs: # лист
acc.append({
"id": node.get("id"),
"name": nm,
"url": "https://www.ikea.com" + url
})
else:
for s in subs:
walk(s, acc)
def collect_leaves(tree):
"""
tree либо dict с ключом 'subs', либо list из таких dict-ов.
Возвращает список «листовых» категорий.
"""
leaves = []
# если пришёл список обходим каждый элемент
if isinstance(tree, list):
for node in tree:
walk(node, leaves)
return leaves
# если dict работаем по старой схеме
if isinstance(tree, dict):
for top in tree.get("subs", []):
walk(top, leaves)
return leaves
# ── main ─────────────────────────────────────────────────────────
def main():
try:
data = fetch_json()
except Exception as e:
sys.exit(f"Не удалось скачать JSON: {e}")
leaves = collect_leaves(data)
print("Найдено категорий-листов:", len(leaves))
# txt
with open(TXT_OUT, "w", encoding="utf-8") as f:
f.write("\n".join(cat["url"] for cat in leaves))
print("Ссылки сохранены:", TXT_OUT)
# xlsx (для удобства)
try:
pd.DataFrame(leaves, columns=["id", "name", "url"]).to_excel(
XLSX_OUT, index=False)
print("Таблица сохранена:", XLSX_OUT)
except Exception as e:
print("⚠️ Excel не записан:", e)
if __name__ == "__main__":
main()