usama-ismail's picture
Rename src/app.py to app.py
6104316 verified
Raw
History Blame Contribute Delete
4.22 kB
import gradio as gr
from playwright.sync_api import sync_playwright
import csv
import time
import random
import re
import pandas as pd
from io import StringIO
def clean_amazon_image(url):
"""Remove ._AC_..._ part to get full-size image"""
if url:
return re.sub(r'\._AC_.*?\.', '.', url)
return url
def scrape_amazon(upc_list, min_delay=3, max_delay=6):
"""Scrape Amazon for UPCs"""
upcs = [x.strip() for x in upc_list.split('\n') if x.strip()]
if not upcs:
return "No UPCs provided!", None
results = []
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
context = browser.new_context(
locale="en-US",
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
)
page = context.new_page()
progress_log = []
for i, upc in enumerate(upcs, start=1):
log_msg = f"Processing ({i}/{len(upcs)}): {upc}"
progress_log.append(log_msg)
try:
page.goto(f"https://www.amazon.com/s?k={upc}", timeout=60000)
time.sleep(random.uniform(min_delay, max_delay))
item = page.query_selector("div[data-component-type='s-search-result']")
if not item:
progress_log.append(f"[NOT FOUND] {upc}")
continue
asin = item.get_attribute("data-asin")
title_el = item.query_selector("h2 span")
title = title_el.inner_text().strip() if title_el else ""
img_el = item.query_selector("img.s-image")
image = img_el.get_attribute("src") if img_el else ""
image = clean_amazon_image(image)
link_el = item.query_selector("h2 a")
link = "https://www.amazon.com" + link_el.get_attribute("href") if link_el else ""
results.append({
"SKU": upc,
"ASIN": asin,
"Title": title,
"Image": image,
"Amazon URL": link
})
progress_log.append(f"βœ“ Found: {title[:60]}")
except Exception as e:
progress_log.append(f"[ERROR] {upc}: {str(e)}")
browser.close()
# Convert to CSV
if results:
df = pd.DataFrame(results)
csv_output = df.to_csv(index=False)
return "\n".join(progress_log), csv_output
else:
return "\n".join(progress_log), None
# Gradio Interface
with gr.Blocks(title="Amazon UPC Scraper") as demo:
gr.Markdown("# πŸ›’ Amazon UPC Scraper")
gr.Markdown("Enter UPCs (one per line) to scrape Amazon product data")
with gr.Row():
with gr.Column():
upc_input = gr.Textbox(
label="UPC Codes (one per line)",
placeholder="Enter UPCs here...\n123456789\n987654321",
lines=10
)
with gr.Row():
min_delay = gr.Slider(1, 10, value=3, label="Min Delay (seconds)")
max_delay = gr.Slider(1, 15, value=6, label="Max Delay (seconds)")
scrape_btn = gr.Button("πŸ” Scrape Amazon", variant="primary")
with gr.Column():
log_output = gr.Textbox(
label="Progress Log",
lines=15,
interactive=False
)
csv_output = gr.File(
label="Download Results (CSV)",
interactive=False
)
scrape_btn.click(
fn=scrape_amazon,
inputs=[upc_input, min_delay, max_delay],
outputs=[log_output, csv_output]
)
gr.Markdown("""
### ⚠️ Important Notes:
- This scraper respects delays to avoid overwhelming Amazon servers
- Large batches may take time to process
- Results are provided as-is; verify data accuracy
""")
if __name__ == "__main__":
demo.launch()