8a78a70ef6
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.8 KiB
5.8 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 | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| scrape_gumroad_discover | function | py | datascience | 1.0.0 | impure | def scrape_gumroad_discover(taxonomy: str, sort: str = 'best_selling', max_products: int = 300, page_size: int = 100) -> list[dict] | Scrapea el marketplace publico de Gumroad Discover usando el endpoint JSON verificado gumroad.com/products/search (taxonomy+sort+from+size). Recolecta los productos de una taxonomy (nicho) ordenados por el criterio elegido y estampa en cada producto el total de la taxonomy (saturacion del nicho). Normaliza cada producto a un dict plano con id, seller_name, ratings, precio (cents/usd), pay-what-you-want/free, native_type, url y metadatos de scrape (taxonomy, total_in_taxonomy, sort_used, rank 0-based). Solo stdlib (urllib+json+time). |
|
false | error_go_core | true |
|
python/functions/datascience/scrape_gumroad_discover_test.py | python/functions/datascience/scrape_gumroad_discover.py |
|
Lista de dicts planos, uno por producto, con exactamente estas claves: id, permalink, name, seller_name, ratings_count, ratings_avg, price_cents, currency_code, price_usd (float = price_cents/100), is_pay_what_you_want (bool), is_free (bool = price_cents==0), native_type, url, taxonomy (el arg), total_in_taxonomy (el 'total' del JSON = saturacion del nicho), sort_used (el arg sort), rank (posicion 0-based en el orden devuelto). |
Ejemplo
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from datascience.scrape_gumroad_discover import scrape_gumroad_discover
# Top best-sellers del nicho "design" en Gumroad Discover
rows = scrape_gumroad_discover(taxonomy="design", sort="best_selling", max_products=300, page_size=100)
print(len(rows), "productos")
print("saturacion del nicho:", rows[0]["total_in_taxonomy"])
print(rows[0])
# {'id': '...', 'permalink': '...', 'name': '...', 'seller_name': '...',
# 'ratings_count': 128, 'ratings_avg': 4.9, 'price_cents': 2900,
# 'currency_code': 'usd', 'price_usd': 29.0, 'is_pay_what_you_want': False,
# 'is_free': False, 'native_type': 'digital', 'url': 'https://...',
# 'taxonomy': 'design', 'total_in_taxonomy': 4213, 'sort_used': 'best_selling', 'rank': 0}
# Productos mas nuevos de un nicho concreto
nuevos = scrape_gumroad_discover(taxonomy="3d", sort="newest", max_products=50)
Cuando usarla
Usala cuando quieras hacer market intelligence sobre productos digitales: descubrir que se vende mas en un nicho de Gumroad, medir la saturacion del nicho (total_in_taxonomy) y capturar precios, valoraciones y vendedores para decidir si un nicho merece la pena o esta saturado. Es la fuente de un pipeline de deteccion de oportunidades de producto digital (grupo market-intel): scrapea varias taxonomies/sorts, cruza los snapshots y prioriza nichos con demanda alta y competencia manejable. Llamala antes de cualquier analisis de catalogo digital; el dict devuelto es plano y esta listo para insertar en una tabla tras añadir snapshot_date/scraped_at.
Gotchas
- ratings.count son REVIEWS, no ventas:
ratings_countcuenta valoraciones dejadas, NO unidades vendidas. Como proxy de ventas hay que multiplicar por un factor incierto (solo una fraccion de compradores valora, y esa fraccion varia por nicho/precio). Trataratings_countcomo un limite inferior ruidoso de la demanda, no como ventas reales. - price=0 no siempre significa gratis util:
price_cents==0marcais_free=True, pero puede tratarse de un producto pay-what-you-want (is_pay_what_you_want=True) con minimo 0, no de un regalo. Cruza siempreis_freeconis_pay_what_you_wantantes de sacar conclusiones de precio. - Ventana de paginacion finita:
page/per_pagese IGNORAN (siempre devuelven desde 0); solofrom+sizepaginan. La ventana es amplia pero finita (from~960 aun devuelve, mas alla se agota). Pedirmax_productsmuy alto puede recibir menos productos de los pedidos: la funcion para cuando una pagina devuelve menos depage_sizeitems. - Cloudflare bloquea sin UA de navegador: el endpoint exige
Accept: application/jsony unUser-Agentde navegador. Sin ello Gumroad/Cloudflare puede devolver una pagina de challenge en HTML (no JSON) o redirigir. La funcion ya envia un UA de Chrome; si aun asi recibe un body no-JSON lanzaRuntimeErrorclaro — en ese caso cae al navegador del ecosistema (browser MCP / CDP). - Moneda no siempre USD:
price_usdes soloprice_cents/100por conveniencia; sicurrency_code != 'usd'el valor NO esta convertido a dolares. Conserva y usacurrency_codepara convertir tu mismo.