Orr*_*her 5 python web-scraping arraybuffer
我正在为 Hoymiles 监控系统开发一个网络爬虫。我可以获得的统计数据之一是历史数据,但我获得的数据格式很奇怪。经过大量研究和平台代码搜索后,我发现在发出的post请求中,除了标头和有效负载之外,他们还使用了一个参数,即responseType:“arraybuffer”。因此,经过更多研究,我发现 arraybuffer 是“一种用于表示通用、固定大小的二进制数据缓冲区的数据类型”。
\n我的代码如下:
\ndef plants_data_historycal(self, authorization):\n\n payload = \'\'\'\n {\n "mode":3,\n "date":"2022-01-20"\n }\n \'\'\'\n\n headers = {\n \'Accept\': \'application/json, text/plain, */*\',\n \'Accept-Encoding\': \'gzip, deflate, br\',\n \'authorization\': authorization,\n \'Content-Type\': \'application/json;charset=UTF-8\',\n \'Origin\': \'https://global.hoymiles.com\',\n \'Referer\': \'https://global.hoymiles.com/platform/login\',\n \'Cookie\': cookie,\n \'User-Agent\': \'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Mobile Safari/537.36\'\n }\n\n response = self.session.post(self.url+\'/pvm-data/api/0/statistics/count_station_eq\', headers=headers, data=payload)\n\n if response.status_code != 200:\n raise RuntimeError("A requisi\xc3\xa7\xc3\xa3o falhou: %s", response)\n\n print(response.text)\n data = BeautifulSoup(response.text, \'html.parser\')\n data = json.loads(data.text)\n\n return data\nRun Code Online (Sandbox Code Playgroud)\n对我的请求的响应如下所示:
\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20Y\npv_eqP\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbd@H\xef\xbf\xbd\xef\xbf\xbd[H\xef\xbf\xbdnH\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbd0H\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbdQH\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbdJH\xef\xbf\xbd\n\xef\xbf\xbdH`\xef\xbf\xbdH\xef\xbf\xbd1\xef\xbf\xbdH\xef\xbf\xbd\xdd\x97H@]sH\xef\xbf\xbd\xef\xbf\xbd_H`j\xef\xbf\xbdH\xef\xbf\xbd!\xef\xbf\xbdH\nRun Code Online (Sandbox Code Playgroud)\nBeatifulSoup之前的response.text
\n\\n\\x011\\n\\x012\\n\\x013\\n\\x014\\n\\x015\\n\\x016\\n\\x017\\n\\x018\\n\\x019\\n\\x0210\\n\\x0211\\n\\x0212\\n\\x0213\\n\\x0214\\n\\x0215\\n\\x0216\\n\\x0217\\n\\x0218\\n\\x0219\\n\\x0220\\n\\x0221\\n\\x0222\\n\\x0223\\x12e\\n\\x05pv_eq\\x12\\\\\\x00\xef\xbf\xbd\xef\xbf\xbdG\\x00\xef\xbf\xbd@H\xef\xbf\xbd\xef\xbf\xbd[H\\x00\xef\xbf\xbdnH\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH\xef\xbf\xbd\\x080H\\x00\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbdQ\\x00H\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdG\xef\xbf\xbd\xef\xbf\xbd\\x02H\xef\xbf\xbdJ\\x03H\xef\xbf\xbd\\r\xef\xbf\xbdH`\xef\xbf\xbdH\xef\xbf\xbd1\xef\xbf\xbdH\xef\xbf\xbd\xdd\x97H@]sH\xef\xbf\xbd\xef\xbf\xbd_H`j\xef\xbf\xbdH\xef\xbf\xbd!\xef\xbf\xbdH\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbdH`z\xef\xbf\xbdH I\xef\xbf\xbdH\nRun Code Online (Sandbox Code Playgroud)\n为了尝试将此字符串转换为可以理解的内容,我尝试使用 Hoymiles 主页 Chrome 浏览器 ( https://global.hoymiles.com/platform/home ) 的检查选项中提供的代码。从那里我发现他们用函数转换了数组缓冲区
\ntransformResponse: [\n function (e) {\n if ("string" == typeof e)\n try {\n e = JSON.parse(e);\n } catch (e) {}\n return e;\n },\n],\nRun Code Online (Sandbox Code Playgroud)\n但即便如此,数组缓冲区还是空的。所以我将响应作为 arraybuffer 转换为 Uint8Array,但我无法理解数据的含义。
\nUint8Array {\n0: 123\n1:34\n10:34\n11:49\n12:48\n13:48\n14:34\n15:44\n16:34\n17: 100\n18:97\n19: 116\n2: 115\n20: 97\n21:34\n22:58\n23:34\n24: 34\n25:44\n26: 34\n27: 109\n28: 101\n29: 115\n3: 116\n30: 115\n31: 97\n32: 103\n33: 101\n34: 34\n35: 58\n36: 34\n37: 116\n38: 111\n39: 107\n4: 97\n40: 101\n41: 110\n42: 32\n43: 118\n44: 101\n45: 114\n46: 105\n47: 102\n48: 121\n49: 32\n5: 116\n50: 101\n51: 114\n52: 114\n53: 111\n54: 114\n55: 46\n56: 34\n57: 125\n6: 117\n7: 115\n8:34\n9:58\n}\nRun Code Online (Sandbox Code Playgroud)\n有谁知道如何将其转化为可读或可理解的数据?
\n所以我不知道您期望从中得到什么数据类型Uint8Array。但以下一些见解可能会帮助您回答您的问题。Uint8Array 类型数组表示 8 位无符号整数的数组。因此,这应该代表什么是含糊不清的。它可以是 String、float、json、int。
因此,我假设您打印的 Uint8Array 输出将键视为数组中的索引位置,而值是数组中该索引处的值。然而索引 50 不是输出中的关键,所以这很令人困惑
无论如何,我制作了一个 Uint8Array,其值的顺序与下面的输出相同。
// Same array you printed out
const lst = [ 123, 34, 115, 116, 97, 116, 117, 115, 34, 58, 34, 49, 48,
48, 34, 44, 34, 100, 97, 116, 97, 34, 58,34, 34, 44, 34, 109,
101, 115, 115, 97, 103, 101, 34, 58, 34, 116, 111, 107, 101,
110, 32, 118, 101, 114, 105, 102, 121, 32, undefined, 114, 114,
111, 114, 46, 34 ]
// Make the Uint8Array
var data = new Uint8Array(lst);
// Print as String
let str = Buffer.from(data).toString('base64');
console.log(str); // output: eyJzdGF0dXMiOiIxMDAiLCJkYXRhIjoiIiwibWVzc2FnZSI6InRva2VuIHZlcmlmeSAAcnJvci4i
// Print as float
const floatValue =new DataView(data.buffer).getFloat64(0);
console.log(floatValue) // output: 1.3718470458079746e+285
// Print as json
function printAsJson(arr) {
let str = "";
for (var i=0; i<arr.byteLength; i++) {
str += String.fromCharCode(arr[i]);
}
var serializedData = JSON.stringify(str);
let message = JSON.parse(serializedData);
console.log(message)
}
printAsJson(data); // output: {"status":"100","data":"","message":"token verify rror."
Run Code Online (Sandbox Code Playgroud)
综上所述,json 是最有意义的,看起来你有一个令牌验证错误。