Saltar al contenido

¿Cómo soluciono automáticamente un JSON no válido? string?

Ya no busques más por otras webs porque llegaste al lugar adecuado, contamos con la respuesta que deseas sin complicaciones.

Solución:

La respuesta de @Michael me dio una idea … no es una idea muy bonita, pero parece funcionar, al menos en su ejemplo: intente analizar el JSON string, y si falla, busque el personaje donde falló en la excepción string1 y reemplace ese carácter.

while True:
    try:
        result = json.loads(s)   # try to parse...
        break                    # parsing worked -> exit loop
    except Exception as e:
        # "Expecting , delimiter: line 34 column 54 (char 1158)"
        # position of unexpected character after '"'
        unexp = int(re.findall(r'(char (d+))', str(e))[0])
        # position of unescaped '"' before that
        unesc = s.rfind(r'"', 0, unexp)
        s = s[:unesc] + r'"' + s[unesc+1:]
        # position of correspondig closing '"' (+2 for inserted '')
        closg = s.find(r'"', unesc + 2)
        s = s[:closg] + r'"' + s[closg+1:]
print result

Es posible que desee agregar algunas comprobaciones adicionales para evitar que esto termine en un bucle infinito (por ejemplo, al máximo de tantas repeticiones como caracteres haya en el string). Además, esto aún no funcionará si un " en realidad va seguido de una coma, como lo señala @gnibbler.

Actualizar: Esto parece funcionar lindo bueno ahora (aunque todavía no es perfecto), incluso si el no escapado " va seguido de una coma o corchete de cierre, ya que en este caso es probable que reciba una queja sobre un error de sintaxis después de eso (nombre de propiedad esperado, etc.) y se remonta al último ". También se escapa automáticamente del cierre correspondiente. " (asumiendo que hay uno).


1) La excepción str es "Expecting , delimiter: line XXX column YYY (char ZZZ)", donde ZZZ es la posición en el string donde ocurrió el error. Sin embargo, tenga en cuenta que este mensaje puede depender de la versión de Python, el json módulo, el sistema operativo o la configuración regional y, por lo tanto, es posible que esta solución deba adaptarse en consecuencia.

Si esto es exactamente lo que devuelve la API, entonces hay un problema con su API. Este JSON no es válido. Especialmente en esta área:

"ads": 
            "sponsored_article": 
                "title": "Образовательный центр "ADVANCE"", <-- here
                "text": "Бизнес.Риторика.Английский язык.Подготовка к школе.Подготовка к ЕГЭ."
            ,
            "warning": null
        

Las comillas dobles de ADVANCE no se escapan. Puede saberlo usando algo como http://jsonlint.com/ para validarlo.

Este es un problema con el " al no escapar, los datos son malos en la fuente si esto es lo que está obteniendo. Necesitan arreglarlo.

Parse error on line 4:
...азовательный центр "ADVANCE"",         
-----------------------^
Expecting '}', ':', ',', ']'

Esto soluciona el problema:

"title": "Образовательный центр "ADVANCE"",

La única solución real y definitiva es pedirle a 2gis que arregle su API.

Mientras tanto, es posible corregir el JSON mal codificado que escapa a las comillas dobles dentro de las cadenas. Si cada key-valor par es seguido por una nueva línea (como parece ser de los datos publicados) la siguiente función hará el trabajo:

def fixjson(badjson):
    s = badjson
    idx = 0
    while True:
        try:
            start = s.index( '": "', idx) + 4
            end1  = s.index( '",n',idx)
            end2  = s.index( '"n', idx)
            if end1 < end2:
                end = end1
            else:
                end = end2
            content = s[start:end]
            content = content.replace('"', '\"')
            s = s[:start] + content + s[end:]
            idx = start + len(content) + 6
        except:
            return s

Tenga en cuenta que algunas suposiciones realizadas:

La función intenta escapar de los caracteres de comillas dobles dentro valor string perteneciendo a key-pares de valores.

Se supone que el texto que se va a escapar comienza después de la secuencia

": "

y termina antes de la secuencia

",n

o

"n

Pasar el JSON publicado a la función da como resultado este valor devuelto


    "api_version": "1.3",
    "response_code": "200",
    "id": "3237490513229753",
    "lon": "38.969916127827",
    "lat": "45.069889625267",
    "page_url": null,
    "name": "ATB",
    "firm_group": 
        "id": "3237499103085728",
        "count": "1"
    ,
    "city_name": "Krasnodar",
    "city_id": "3237585002430511",
    "address": "Turgeneva,   172/1",
    "create_time": "2008-07-22 10:02:04 07",
    "modification_time": "2013-08-09 20:04:36 07",
    "see_also": [
        
            "id": "3237491513434577",
            "lon": 38.973110606808,
            "lat": 45.029031222211,
            "name": "Advance",
            "hash": "5698hn745A8IJ1H86177uvgn94521J3464he26763737242Cf6e654G62J0I7878e",
            "ads": 
                "sponsored_article": 
                    "title": "Center "ADVANCE"",
                    "text": "Business.English."
                ,
                "warning": null
            
        
    ]

Tenga en cuenta que puede personalizar fácilmente la función si sus necesidades no están completamente satisfechas.

Te mostramos reseñas y puntuaciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *