Un parser de precios japoneses debe devolver un importe junto con la evidencia de divisa, el texto original y la base fiscal. Selecciona primero un único campo de oferta, controla la normalización Unicode y retén las entradas ambiguas. Un campo parsed todavía necesita comprobaciones antes de convertirse en un registro de monitoreo aceptado.
El ejemplo descargable en Python hace explícito ese límite. Sus 36 casos sintéticos sin conexión produjeron 36 clasificaciones esperadas: 11 campos parseados, 25 resultados de revisión y cero fallos del fixture. No se probó ninguna tienda japonesa ni ningún proxy. El resultado útil es un conjunto reproducible de decisiones, incluidos los casos en que el parser se niega a elegir un precio.
Una indicación de precio puede contener dos importes legítimos
La Agencia Nacional de Impuestos de Japón (NTA) da este ejemplo en su guía sobre la indicación del precio total:
10,000円(税込価格11,000円)El importe que incluye impuestos de forma explícita es de 11.000 yenes, aunque 10.000 aparece primero. Los ejemplos de la NTA permiten indicaciones que contienen cifras con y sin impuestos. Tomar el primer número perdería esa distinción. NTA n.º 6902, ejemplos de indicación.
Eliminar todo lo que no sea un dígito es peor: aplicado a esta cadena, re.sub(r"\D", "", text) de Python produce 1000011000. El parser suministrado devuelve review con el motivo unsupported_or_multiple_price_text. No elige un importe de un contenedor con varios precios.
Resuélvelo en una etapa anterior: identifica el importe previsto y su etiqueta dentro de la oferta seleccionada, conservando el contexto de la fuente. Si tu extractor no puede distinguir los importes, mantén el registro en revisión. Una obligación general de indicación no prueba la base fiscal de un campo extraído arbitrario.
Exige contexto de divisa antes de parsear
El carácter ¥ no demuestra que la divisa sea el yen japonés. Unicode especifica U+00A5 tanto para el yen japonés como para el yuan chino, con independencia del estilo del glifo. Obtén un contexto de divisa explícito para la misma oferta antes de suministrar JPY. Unicode 17, «Yen and Yuan».
La función solo acepta tres claves, con text limitado a una cadena de entre 1 y 200 caracteres. Esta es una entrada sintética del fixture, cuya referencia de evidencia es, deliberadamente, una etiqueta del fixture:
{
"text": "¥1,298(税込)",
"currency": "JPY",
"currency_evidence": "fixture.selected_offer.priceCurrency"
}Para esa entrada, el resultado registrado es:
{
"original": "¥1,298(税込)",
"status": "parsed",
"normalized": "¥1,298(税込)",
"amount_yen": 1298,
"currency": "JPY",
"currency_evidence": "fixture.selected_offer.priceCurrency",
"tax_basis": "included",
"tax_label": "税込"
}En un adaptador, llama a parse_price(record) del módulo descargado con esas tres claves. Mantén la identidad del producto, la URL, la marca de tiempo y el resto del contexto de monitoreo en un registro exterior; las claves adicionales en la entrada de esta función devuelven invalid_record.
La referencia de evidencia es una afirmación de quien llama. La función exige una cadena no vacía, pero no la recupera ni la autentica. Una sonda del autor con una referencia fabricada a propósito siguió devolviendo parsed. Por tanto, suministrar JPY porque la página tiene un glifo con forma de yen anularía el contrato previsto aunque el parser lo dé por bueno. Comprueba por separado la evidencia de divisa subyacente y conserva los conflictos.
Controla la normalización antes de que cambie el campo
Los dígitos de ancho completo pueden representar dígitos decimales normales, pero la normalización de compatibilidad también cambia otros caracteres. La forma NFKC de Unicode puede borrar distinciones que van más allá del ancho; Python la expone mediante unicodedata.normalize. Dígitos de compatibilidad de Unicode, guía de normalización, unicodedata de Python.
Este parser comprueba cada carácter antes de normalizar el campo completo. Permite cambios en el ASCII de ancho completo U+FF01–U+FF5E, el espacio ideográfico U+3000 y el yen de ancho completo U+FFE5. Los demás caracteres que cambian con NFKC pasan a revisión. La gramática se comprueba después de la normalización; una conversión de ancho permitida no convierte por sí sola una entrada en un precio.
Ese orden importa para ¥①298(税込) y ¥¹298(税込). Un plegado de compatibilidad a ciegas puede convertir el carácter encerrado en un círculo o en superíndice en un dígito normal. El fixture retiene ambos como unsupported_compatibility_character. También retiene las barras invertidas ASCII y de ancho completo; el aspecto de un carácter en una fuente tipográfica no lo convierte en un signo de yen.
Conserva original junto a normalized, como hace arriba el registro parseado con éxito. Esta política con salvaguardas es específica del parser descargado. No es una recomendación para aplicar NFKC indiscriminadamente a nombres de producto, identificadores o texto arbitrario de una página.
Conserva la base fiscal sin calcular impuestos
El parser acepta una única expresión en yenes enteros: ¥1298, 1298円 o JPY 1298, con comas opcionales correctamente agrupadas. Una etiqueta de impuestos final admitida puede aparecer entre paréntesis o tras un espacio en blanco. Asigna 税込 y 税込価格 a included; 税抜, 税抜き y 税別, a excluded. La ausencia de etiqueta produce unspecified.
A continuación, algunos resultados seleccionados del fixture ejecutado. Salvo que se indique otra cosa, la entrada tiene currency: "JPY" y la referencia de evidencia sintética mostrada arriba.
| Campo de entrada | Resultado | Consecuencia para una comparación posterior |
|---|---|---|
¥1,298(税込) | parsed: 1298, included | Conserva la base con impuestos incluidos junto al importe. |
1,180円(税抜) | parsed: 1180, excluded | No lo compares en silencio como si tuviera la misma base que un importe con impuestos incluidos. |
1,298円 | parsed: 1298, unspecified | Si el trabajo requiere una base fiscal conocida, ese requisito sigue sin resolver. |
10,000円(税込価格11,000円) | review | Selecciona el campo previsto y aporta evidencia de él antes de parsear. |
12,98円(税込) | review | La agrupación no cumple esta gramática. |
¥①298(税込) | review | Un cambio de compatibilidad no admitido se retiene antes de la normalización. |
¥1298(税込), divisa ausente o CNY | review | Un glifo conocido no puede aportar el contexto JPY requerido. |
No hay cálculo de tipo impositivo, conversión de divisas ni multiplicador de céntimos. amount_yen es un entero según el contrato de entrada en yenes enteros de este parser; no define las unidades que usa cada API. No derives un valor bruto o neto ausente a partir del número cercano.
La gramática también retiene rangos, pagos a plazos, puntos, precios múltiples, negativos, decimales, unidades numéricas en kanji, etiquetas de impuestos antepuestas y ceros a la izquierda. Algunos pueden ser presentaciones válidas de una tienda que quedan fuera de este alcance. Un resultado review significa que la entrada queda sin resolver según esta gramática, no que la indicación del comerciante no sea válida.
Ejecuta el mismo fixture sin conexión
Descarga parse_price.py y fixtures.json en un mismo directorio. El script usa la biblioteca estándar de Python; el README describe el contrato de entrada para Python 3.10 o posterior y sus límites. Ejecuta:
python3 parse_price.py fixtures.json > replay.jsonEl comando no hace ninguna petición de red. Compara replay.json con el results.json publicado. Una ejecución que coincide informa cases: 36, passed: 36 y failed: 0. Los 25 resultados de revisión son decisiones esperadas, así que no cuentan como fallos del fixture.
El fixture comprueba cada campo esperado declarado y conserva las salidas reales completas. El código de salida 0 significa que las expectativas del fixture coincidieron; el 1, que al menos una no coincidió; el 2 indica un fixture no válido o ilegible. Ninguno es una señal de aceptación de una tienda.
El registro del entorno original documenta Python 3.14.7 con la base de datos Unicode 16.0.0. La reejecución del autor en Python 3.14.8, también con la base de datos Unicode 16.0.0, produjo el mismo JSON de resultados completo. Citar la documentación de Unicode 17 no significa que el ejecutable usara una base de datos Unicode 17.
Decide si un campo parseado es utilizable
Antes de aceptar un registro de monitoreo, vincula el campo al producto y la variante exactos, conserva la fuente y la hora de observación, valida la evidencia de divisa y resuelve la base de precio que requiere tu comparación. Comprueba la cantidad, la condición de socio, las condiciones de venta y el contexto de entrega cuando el trabajo dependa de ellos. Son decisiones ajenas a este parser.
Por ejemplo, el campo de 1298 yenes con impuestos incluidos y el de 1180 yenes sin impuestos del fixture se parsean los dos. Eso no convierte su diferencia numérica en un cambio de precio medido. Un campo sin etiqueta también puede parsearse y seguir sin ser adecuado para una comparación que requiera precios con impuestos incluidos.
El caso de validación de precio y divisa, que es un análisis aparte, aborda las señales contradictorias de la oferta y de la tienda. Si tu recolección también requiere una salida japonesa o un acceso móvil concreto, usa la guía de evaluación de proxies de Japón para esa evidencia. Un resultado de parseo local no aporta ninguna evidencia sobre el país, la red o la disponibilidad de una salida.
Método: investigación de fuentes y síntesis asistidas por agente, con fixtures sintéticos ejecutados y la sonda de límites descrita aparte, el 6 de octubre de 2026. Estos casos demuestran el comportamiento indicado del parser; no son una muestra de minoristas japoneses ni un benchmark de precisión. No se probó ninguna tienda, ningún proxy ni ningún cálculo de impuestos.
Avísame cuando se abra el acceso. Un solo correo cuando se abra el acceso. Nada más.