763e06c127
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.4 KiB
4.4 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, tested, tests, test_file_path, file_path, params, output
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | tested | tests | test_file_path | file_path | params | output | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| parse_amazon_ranking_html | function | py | datascience | 1.0.0 | pure | def parse_amazon_ranking_html(html: str, marketplace: str = 'amazon.es', list_type: str = 'bestsellers', max_items: int = 50) -> list[dict] | Parser PURO de HTML de rankings Amazon (Best Sellers y Movers & Shakers): recibe el HTML de la pagina (de requests o de outerHTML renderizado por CDP) y devuelve una lista de productos (rank, ASIN, titulo, precio, rating, reseñas, pct_change). Nucleo compartido por el scraper HTTP y el scraper CDP. |
|
false |
|
true |
|
python/functions/datascience/parse_amazon_ranking_html_test.py | python/functions/datascience/parse_amazon_ranking_html.py |
|
Lista de dicts, uno por producto, con exactamente estas claves: marketplace, list_type, category (siempre None aqui — lo rellena el caller que conoce la URL), rank, asin, title, price, currency, rating, reviews, pct_change, url. None donde no haya dato. price/rating/pct_change son float; rank/reviews son int. pct_change solo se rellena en movers_shakers. HTML vacio o sin cards -> lista vacia (nunca lanza). |
Ejemplo
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from datascience.parse_amazon_ranking_html import parse_amazon_ranking_html
# `html` puede venir de requests.get(...).text o de un outerHTML renderizado por CDP.
html = open("/tmp/amazon_grid.html").read()
rows = parse_amazon_ranking_html(html, marketplace="amazon.es", list_type="movers_shakers", max_items=30)
print(len(rows), "productos")
print(rows[0])
# {'marketplace': 'amazon.es', 'list_type': 'movers_shakers', 'category': None,
# 'rank': 1, 'asin': 'B0...', 'title': '...', 'price': 13.95, 'currency': 'EUR',
# 'rating': 4.0, 'reviews': 666, 'pct_change': 150.0, 'url': 'https://www.amazon.es/dp/B0...'}
Cuando usarla
Usala cuando ya tengas el HTML de una pagina de ranking de Amazon (Best Sellers o Movers & Shakers) y quieras extraer los productos sin volver a escribir selectores DOM. Es el bloque de parsing reutilizable: la usan tanto scrape_amazon_bestsellers (fetch HTTP con requests) como scrape_amazon_movers_cdp (fetch renderizado via Chrome DevTools Protocol). Si construyes otro fetcher (proxy, browser MCP, HAR replay), pasale el HTML aqui en vez de duplicar el parser.
Notas
- Funcion pura: sin red ni I/O; para un HTML fijo devuelve siempre lo mismo. Por eso es testeable con fixtures y compartible entre estrategias de fetch.
- Plantillas multiples: Amazon sirve varias plantillas DOM a la vez (A/B test) y las rota. Cada campo usa varios selectores fallback; un campo que ninguna plantilla conocida expone se devuelve
Noneen vez de petar. - Seleccion de cards: prioriza el wrapper del grid (
div[id="gridItemRoot"]) sobre el faceout interno, porque el badge de rank (span.zg-bdg-text) es hermano del faceout DENTRO del wrapper — seleccionar el faceout solo perderia el rank. - pct_change defensivo: apunta solo al badge de subida de ranking de movers (
.zg-percent-changey variantes), NO al%generico de descuento/ahorro (apex-savings-percent) de cards de oferta, que daria un pct_change falso. - category = None: el parser no conoce la URL, asi que deja
categoryenNone; el caller (que si sabe que categoria pidio) lo rellena. - rank fallback posicional: si Amazon no renderiza el badge de rank, se usa la posicion (1-indexada) del item en el grid.