Files
DBAdmin/inbox/wordpress/get-wp.py
T
2026-05-18 06:40:19 +00:00

119 lines
4.1 KiB
Python

import time
import pandas as pd
import undetected_chromedriver as uc
from bs4 import BeautifulSoup
from selenium.webdriver.common.keys import Keys
import os
import json
def scrape_alternativeto(i):
url = f'https://alternativeto.net/category/business-and-commerce/cms/?p={i}'
# Konfiguracja Selenium (undetected-chromedriver)
options = uc.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = uc.Chrome(options=options)
driver.get(url)
# Poczekaj na załadowanie strony
time.sleep(2)
# Akceptacja cookies jeśli pojawi się banner
try:
consent_button = driver.find_element("xpath", "//button[contains(., 'Consent') or contains(., 'Zgadzam się')]")
consent_button.click()
time.sleep(1)
except Exception:
pass # Jeśli nie ma bannera, przechodzimy dalej
# Przewiń stronę, aby załadować więcej CMS-ów
body = driver.find_element("tag name", "body")
for _ in range(10): # Możesz zwiększyć, jeśli nie pobiera wszystkich wyników
body.send_keys(Keys.PAGE_DOWN)
time.sleep(1)
# Pobierz HTML strony
html = driver.page_source
driver.quit()
# Parsowanie HTML za pomocą BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
# **🔍 ZMIENNE: Ustaw poprawne selektory CSS dla CMS-ów**
cms_items = soup.select("div[id^='app-item-']") # Pobiera wszystkie CMS-y
if not cms_items:
print("⚠️ Nie znaleziono CMS-ów! Sprawdź poprawny selektor w przeglądarce.")
return
# Lista na wyniki
extracted_data = []
for item in cms_items:
# Nazwa narzędzia
name_tag = item.select_one("div.flex.flex-col.w-full.gap-3 > div > div.min-w-\\[180px\\].md\\:min-w-0 > a > h2")
name = name_tag.text.strip() if name_tag else "N/A"
# Link
link_tag = item.select_one("div.flex.flex-col.w-full.gap-3 > div > div.min-w-\\[180px\\].md\\:min-w-0 > a")
link = f"https://alternativeto.net{link_tag['href']}" if link_tag and link_tag.has_attr('href') else "N/A"
# Obrazek
image_tag = item.select_one("div.flex.flex-col.w-full.gap-3 > div > div.flex.items-center.lg\\:hidden > a > div > img")
image = image_tag['src'] if image_tag and image_tag.has_attr('src') else "N/A"
extracted_data.append({
"name": name,
"link": link,
"image": image
})
if not extracted_data:
print("⚠️ Nie udało się wydobyć żadnych danych.")
return
# Dopisywanie do istniejących danych JSON (jeśli plik istnieje)
json_path = "cms_alternatives.json"
if os.path.exists(json_path):
with open(json_path, "r", encoding="utf-8") as f:
try:
existing_data = json.load(f)
except Exception:
existing_data = []
else:
existing_data = []
# Dodaj nowe dane, unikając duplikatów po nazwie i linku
existing_keys = {(d["name"], d["link"]) for d in existing_data if "name" in d and "link" in d}
for row in extracted_data:
if (row["name"], row["link"]) not in existing_keys:
existing_data.append(row)
# Zapisz zaktualizowane dane
with open(json_path, "w", encoding="utf-8") as f:
json.dump(existing_data, f, indent=4, ensure_ascii=False)
print("✅ Dane dopisane do cms_alternatives.json")
# Analogicznie dla CSV
import pandas as pd
df_new = pd.DataFrame(extracted_data)
csv_path = "cms_alternatives.csv"
if os.path.exists(csv_path):
df_existing = pd.read_csv(csv_path, encoding="utf-8")
df_all = pd.concat([df_existing, df_new], ignore_index=True)
df_all = df_all.drop_duplicates(subset=["name", "link"])
else:
df_all = df_new
df_all.to_csv(csv_path, index=False, encoding="utf-8")
print("✅ Dane dopisane do cms_alternatives.csv")
# Uruchamiamy skrypt
if __name__ == "__main__":
for i in range(15):
print(f"🔄 Strona {i + 12}...")
j = i + 12
scrape_alternativeto(j)
time.sleep(2)
## scrape_alternativeto()