用Python从html页面提取JSON数据



我对html &在Raspberry Pi项目中,我在Python中以可用的格式提取数据时遇到了一些困难。

我使用的设备输出一些实时数据在一个html页面的格式的wifi链接。虽然页面上显示的数据可以更改,但我现在只关心从单个页面获取数据。当在notepad++中查看时,页面看起来像:

<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><style>.b{position:absolute;top:0;bottom:0;left:0;right:0;height:100%;background-color:#000;height:auto !important;}.f{border-radius: 10px;font-weight:bold;position:absolute;top:50%;left:0;right:0;margin:auto;background:#024d27;padding:50px;box-sizing:border-box;color:#FF0;margin:30px;box-shadow:0px 2px 18px -4px #0F0;transform:translateY(-50%);}#V{font-size:96px;}#U{font-size: 56px;}#N{font-size: 36px;}</style></head><body><div class="b"><div class="f"><span id="N">Voltage</span><br><span id="V">12.53</span>&nbsp;<span id="U">V</span><br></div></div><script>reqData();setInterval(reqData, 200);function reqData() {var xhr = new XMLHttpRequest();xhr.onload = function() {if (this.status == 200) {var data = JSON.parse(xhr.responseText);document.getElementById('N').innerHTML = data.n;document.getElementById('V').innerHTML = data.v;document.getElementById('U').innerHTML = data.u;} else {document.getElementById('N').innerHTML = "?";document.getElementById('V').innerHTML =  "?";document.getElementById('U').innerHTML = "?";}};xhr.open('GET', 'readVal', true);xhr.send();}</script></body></html>

正如你所看到的,这是一个相当简单的页面,它只是提供了我想要提取的信息,呈现在一个绿色的盒子里,黑色背景上有黄色的文字。

从盯着信息看一点,我试图提取的信息是与Span ID = 'V'(电压),'N'(名称)和'U'(单位)相关的信息。

数据在网页上实时显示(即每200ms更新一次(我认为)而不刷新页面),我想尽可能频繁地提取值。

我已经尝试了几个不同的代码块/方法,这似乎是我目前能够获得任何成功的唯一一个:

import urllib.request, json, html
data = urllib.request.urlopen("http://192.168.4.1").read()
print (data)

这返回给我正确的页面的html源代码(尽管有大约5秒的延迟,这可能只是与Pi Zero的低规格有关,我正在运行它)。

然而,我似乎无法从中提取JSON数据。我试过了:

data_json = json.loads(data)

但这给了我一个JSONDecodeError:期望值:第1行第1列(char 0),我假设这是因为"数据"是HTML代码和JSON的混合。我还注意到,我试图检索的实际变量信息(电压,12.53 &V(来自顶部的示例源页面)只是显示为'?'占位符,当我使用urllib打开页面时,而不是加载页面上显示的实际值。

有谁能给我一些建议吗?提前感谢,史蒂夫。

正如您从错误消息和原始HTML代码中注意到的那样,您从设备获得的结果不是json数据,而是HTML与javascript。它看起来像你发布的HTML是一个ajax请求(javascript GET请求)到一些本地端点(/readVal也许?)。

尝试在浏览器中打开http://192.168.4.1,打开开发工具,并观察页面在底层发出的网络请求—特别是寻找一些XHR请求。查看请求URL和响应——我打赌你会发现一些本地端点返回你想要的原始json数据。

或者试试http://192.168.4.1/readVal,看看是不是这样。

最新更新