Antique_Auth_API / code /web_scraper_ebay.py
hatamo's picture
added main for manual input
7c3f29a
Raw
History Blame
4.48 kB
import os
import requests
from apify_client import ApifyClient
from dotenv import load_dotenv
import json
# --- CONFIGURATION ---
# Load environment variables from the .env file (if it exists)
load_dotenv()
ACTOR_ID = "vulnv/ebay-product-scraper"
# --- HELPER FUNCTIONS ---
def sanitize_name(text):
"""Sanitizes text by removing Polish characters and special symbols for a folder name."""
polish_chars = {
"ą": "a",
"ć": "c",
"ę": "e",
"ł": "l",
"ń": "n",
"ó": "o",
"ś": "s",
"ź": "z",
"ż": "z",
}
text = text.lower()
result = ""
for char in text:
if char in polish_chars:
result += polish_chars[char]
elif char.isalnum():
result += char
else:
result += "_"
# Remove double underscores
while "__" in result:
result = result.replace("__", "_")
return result.strip("_")
def get_high_res_ebay_image(url):
"""Replaces the size code in the eBay link with s-l1600 (Max quality)."""
if not url: return None
sizes = ["s-l64", "s-l140", "s-l300", "s-l400", "s-l500", "s-l960"]
for size in sizes:
if size in url:
return url.replace(size, "s-l1600")
if "ebayimg.com" in url and "s-l1600" not in url:
parts = url.split("/")
last_part = parts[-1]
if "s-l" in last_part:
return url.replace(last_part[:last_part.find(".")], "s-l1600")
return url
def get_api_token():
"""Retrieves token from .env or asks the user."""
token = os.getenv("APIFY_TOKEN")
if token:
print("Info: API Token loaded from .env file.")
return token
return AttributeError("API Token is required but not provided.")
def get_ebay_data(url):
apify_token = get_api_token()
if not apify_token:
print("ERROR: API Token is required.")
return
print(f"\n--- SENDING REQUEST TO APIFY ---")
client = ApifyClient(apify_token)
run_input = { "product_urls": [url] }
try:
run = client.actor(ACTOR_ID).call(run_input=run_input)
dataset_items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
if not dataset_items:
print("Apify finished the job but returned no data.")
return
item = dataset_items[0]
# --- DATA MAPPING ---
# TITLE
title = item.get("name") or item.get("title") or "untitled_ebay"
# PRICE
price = item.get("price", "N/A")
currency = item.get("currency", "")
# DESCRIPTION
description = item.get("description", "No text description available.")
# PARAMETERS
parameter_list = []
raw_props = item.get("additionalProperties", [])
if isinstance(raw_props, list):
for prop in raw_props:
p_name = prop.get("name")
p_val = prop.get("value")
if p_name and p_val:
parameter_list.append(f"{p_name}: {p_val}")
if item.get("sku"): parameter_list.insert(0, f"SKU: {item.get('sku')}")
# IMAGES
unique_links = set()
main_img = item.get("mainImage", {}).get("url")
if main_img:
unique_links.add(get_high_res_ebay_image(main_img))
raw_images = item.get("images", [])
for img_entry in raw_images:
if isinstance(img_entry, dict):
raw_url = img_entry.get("url")
if raw_url:
unique_links.add(get_high_res_ebay_image(raw_url))
elif isinstance(img_entry, str):
unique_links.add(get_high_res_ebay_image(img_entry))
print(f"Found {len(unique_links)} unique images (High-Res).")
return {
"title": title,
"sanitized_title": sanitize_name(title),
"url": url,
"description": description,
"parameters": parameter_list,
"image_urls": list(unique_links),
"image_count": len(unique_links),
"price": f"{price} {currency}"
}
except Exception as e:
print(f"Critical error occurred: {e}")
# --- USAGE ---
if __name__ == "__main__":
link = input("Enter the eBay offer link: ")
data = get_ebay_data(link)
print(json.dumps(data, indent=4, ensure_ascii=False))