2016-08-19 6 views
0

модуль WebOb питона по умолчанию возвращает текст/html ответов, в частности, ServerErorr-х, и они в конечном итоге встраивание ошибку JSON Paylod в теле HTML responseText содержит следующее:Анализировать JSON из HTML responseText

<html> 
<head> 
    <title>503 Service Unavailable</title> 
</head> 
<body> 
<h1>503 Service Unavailable</h1> 
{ 
    "status": "object-specific error", 
    "payload": { 
      "Message": "Unable to list resources", 
      "HTTP Method": "GET", 
      "URI": "api/myManager/1.0/Node", 
      "Operation": "LIST", 
      "Object": { 
        "Name": "myManager.Node", 
        "Interface": "Node" 
      }, 
      "Version": { 
        "Major": 1, 
        "Minor": 0 
      } 
     } 
}<br /><br /> 
</body> 
</html> 

Использование Javascript на стороне клиента лучший способ извлечь JSON, встроенный в HTML? Каков наилучший способ извлечь этот объект JSON, встроенный в HTML?

+0

Разделите его на структуру DOM, затем найдите текстовый элемент после элемента 'h1'. – Barmar

+0

Я думаю, что лучший способ - обработать ошибку на стороне сервера и вернуть ответ как 'json'. Нет прямого способа разбора 'json', встроенного в html, как вы показали. Если вам действительно нужно извлечь json отсюда, вам нужно прочитать dom (это единственный способ) отдельную строку 'json', а затем использовать [JSON.parse()] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse) –

+1

Извлечение JSON из HTML - это плохая практика. Вы должны изменить сценарий на стороне сервера, чтобы вернуть JSON только – KmasterYC

ответ

-1

Использование регулярных выражений для разбора (на самом деле не надежный, но эффективный) импорт повторно импорт JSON

content = """\ 
<html> 
<head> 
    <title>503 Service Unavailable</title> 
</head> 
<body> 
<h1>503 Service Unavailable</h1> 
{ 
    "status": "object-specific error", 
    "payload": { 
      "Message": "Unable to list resources", 
      "HTTP Method": "GET", 
      "URI": "api/myManager/1.0/Node", 
      "Operation": "LIST", 
      "Object": { 
        "Name": "myManager.Node", 
        "Interface": "Node" 
      }, 
      "Version": { 
        "Major": 1, 
        "Minor": 0 
      } 
     } 
}<br /><br /> 
</body> 
</html>""" 

mo = re.search(r"</h1>(.*?)<br", content, flags=re.DOTALL) 
if mo: 
    data = mo.group(1) 
    obj = json.loads(data) 
    print(obj) 

Вы получите:

{'payload': {'Operation': 'LIST', 'HTTP Method': 'GET', 
'URI': 'api/myManager/1.0/Node', 
'Message': 'Unable to list resources', 
'Version': {'Major': 1, 'Minor': 0}, 
'Object': {'Interface': 'Node', 'Name': 'myManager.Node'}}, 
'status': 'object-specific error'} 

Или, используя lxml:

import json 
from lxml import etree 

content = """\ 
<html> 
... 
</html>""" 

tree = etree.XML(content) 

h1 = tree.xpath("/html/body/h1[1]")[0] 
data = h1.tail 
obj = json.loads(data) 

Тот же результат

+0

спасибо за ответ .. однако я пытаюсь добиться разбора с использованием Javascript, а не Python ... возможно, я не был достаточно ясен в заголовке –

0

Итак, я согласен с тем, что лучшим решением является обеспечение того, что сервер возвращает только JSON, но это быстрое средство для достижения этого через Javascript на стороне клиента, как предлагал @Barmer, проанализировать html для DOM, получить text childNode внутри тела и запустить JSONParse на нем.

var responseStr = '<html>' + 
        '<head>' + 
        ' <title>503 Service Unavailable</title>' + 
        '</head>' + 
        '<body>' + 
        '<h1>503 Service Unavailable</h1>' + 
        '{' + 
        ' "status": "object-specific error",' + 
        ' "payload": {' + 
        ' "Message": "Unable to list resources",' + 
        ' "HTTP Method": "GET",' + 
        ' "URI": "api/myManager/1.0/Node",' + 
        ' "Operation": "LIST",' + 
        ' "Object": {' + 
        '  "Name": "myManager.Node",' + 
        '  "Interface": "Node"' + 
        ' },' + 
        ' "Version": {' + 
        '  "Major": 1,' + 
        '  "Minor": 0' + 
        ' }' + 
        ' }' + 
        '}<br /><br />' + 
        '</body>' + 
        '</html>'; 
var parser = new DOMParser(); 
var doc = parser.parseFromString(responseStr, "text/html"); 
var items = doc.body.getElementsByTagName("*"); 
var json_obj; 

for (var i = 0, len = doc.body.childNodes.length; i < len; i++) { 
    if (doc.body.childNodes[i].nodeName == "#text") { 
     json_obj = JSON.parse(doc.body.childNodes[i].data); 
     break; 
    } 
} 

// You can access json directly now e.g. 
console.log(json_obj.status); 
console.log(json_obj.payload['HTTP Method']); 
Смежные вопросы