【问题标题】:Web scraping in Python - Arraybuffer to data readablePython 中的 Web 抓取 - Arraybuffer 到数据可读
【发布时间】:2022-01-22 02:12:52
【问题描述】:

我正在为 Hoymiles 监控系统开发一个网络爬虫。我可以得到的统计数据之一是历史数据,但我得到的数据格式很奇怪。经过大量的研究和在平台代码中的搜索,我发现在发出的post请求中,除了headers和payload之外,他们使用了一个参数,即responseType:“arraybuffer”。因此,经过更多研究,我发现arraybuffer是“一种用于表示通用的、固定大小的二进制数据缓冲区的数据类型”。

我的代码如下:

def plants_data_historycal(self, authorization):

    payload = '''
        {
            "mode":3,
            "date":"2022-01-20"
        }
    '''

    headers = {
        'Accept': 'application/json, text/plain, */*',
        'Accept-Encoding': 'gzip, deflate, br',
        'authorization': authorization,
        'Content-Type': 'application/json;charset=UTF-8',
        'Origin': 'https://global.hoymiles.com',
        'Referer': 'https://global.hoymiles.com/platform/login',
        'Cookie': cookie,
        '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'
    }

    response = self.session.post(self.url+'/pvm-data/api/0/statistics/count_station_eq', headers=headers, data=payload)

    if response.status_code != 200:
        raise RuntimeError("A requisição falhou: %s", response)

    print(response.text)
    data = BeautifulSoup(response.text, 'html.parser')
    data = json.loads(data.text)

    return data

对我的请求的响应如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Y
pv_eqP��G�@H��[H�nH���H�0H��G���G�QH���G��H�JH�
�H`�H�1�H�ݗH@]sH��_H`j�H�!�H

BeatifulSoup 之前的 response.text

\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��G\x00�@H��[H\x00�nH���H�\x080H\x00��G���G�Q\x00H���G��\x02H�J\x03H�\r�H`�H�1�H�ݗH@]sH��_H`j�H�!�H���H`z�H I�H

为了尝试将此字符串转换为可以理解的内容,我尝试使用 Hoymiles 主页 Chrome 浏览器 (https://global.hoymiles.com/platform/home) 的检查选项中提供的代码。从那里我发现他们用函数转换了arraybuffer

transformResponse: [
    function (e) {
            if ("string" == typeof e)
                   try {
                        e = JSON.parse(e);
                   } catch (e) {}
                        return e;
     },
],

但即便如此,arraybuffer 还是空的。所以我把作为arraybuffer的response变成了一个Uint8Array,但是我看不懂数据是什么意思。

Uint8Array {
0: 123
1:34
10:34
11:49
12:48
13:48
14:34
15:44
16:34
17: 100
18:97
19: 116
2: 115
20: 97
21:34
22:58
23:34
24: 34
25:44
26: 34
27: 109
28: 101
29: 115
3: 116
30: 115
31: 97
32: 103
33: 101
34: 34
35: 58
36: 34
37: 116
38: 111
39: 107
4: 97
40: 101
41: 110
42: 32
43: 118
44: 101
45: 114
46: 105
47: 102
48: 121
49: 32
5: 116
50: 101
51: 114
52: 114
53: 111
54: 114
55: 46
56: 34
57: 125
6: 117
7: 115
8:34
9:58
}

有谁知道如何将其转化为可读或可理解的数据?

【问题讨论】:

  • 这可能不是您要找的答案。但我总是发现使用 puppeteer 库在 javascript 中进行网页抓取是一种更愉快的体验。此外,您可以很容易地在 javascript 中将数组缓冲区转换为字符串 (stackoverflow.com/questions/6965107/…)。如果你知道python学习javascript会很容易。
  • 对不起,回答迟了,但我发现实际上这已经是字符串而不是字节的python答案。我试图弄清楚如何将 arraybuffer 变成 javascript 中可以理解的东西,但我做不到。我把这个arraybuffer变成了一个Uint8Array,但是我不明白数据的含义。我将编辑问题并添加数组:)
  • 你有一个令牌验证错误阅读下面我的帖子,如果它对你有帮助,请接受答案:)
  • 我用我收到的你的代码发了一个帖子,实际上我从请求中得到的响应是 json 格式

标签: python web-scraping arraybuffer


【解决方案1】:

所以我不知道您希望从 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."

总而言之,json 是最有意义的,而且您似乎遇到了令牌验证错误。

【讨论】:

    【解决方案2】:

    实际上我遇到了令牌验证错误,因为我在 javascript 代码中使用了过期版本的授权令牌。所以我用更新的令牌编译了代码并使用了你的代码。

    代码

    const lst = [10, 1, 49, 10, 1, 50, 10, 1, 51, 10, 1, 52, 10, 1, 53, 10, 1, 54, 10, 1, 55, 10, 1, 56, 10, 1, 57, 10, 2, 49, 48, 10, 2, 49, 49, 10, 2, 49 , 50, 10 , 2, 49 , 51, 10 , 2, 49 , 52 , 10 , 2 , 49 , 53 , 10 , 2 , 49 , 54 , 10 , 2 , 49 , 55 , 10 , 2 , 49 , 56 , 10 , 2 , 49 , 57 , 10 , 2 , 50 , 48 , 10 , 2 , 50 , 49 , 10 , 2 , 50 , 50 , 10 , 2 , 50 , 51 , 10 , 2 , 50 , 52 , 18 , 105 , 10 , 5 , 112 , 118 , 95 , 101 , 113 , 18 , 96 , 0 , 244 ,  214 ,  71 ,  0 ,  144 ,  64 ,  72 ,  128 ,  237 ,  91 ,  72 ,  0 ,  162 ,  110 ,  72 ,  128 ,  138 ,  130 ,  72 ,  128 ,  8 ,  48 ,  72 ,  0 ,  236 ,  252 ,  71 ,  128 ,  209 ,  205 ,  71 ,  192 ,  81 ,  0 ,  72 ,  128 ,  189 ,  253 ,  71 ,  128 ,  156 ,  2 ,  72 ,  192 ,  74 ,  3 ,  72 ,  128 ,  13 ,  128 ,  72 ,  96 ,  234 ,  150 ,  72 ,  192 ,  49 ,  161 ,  72 ,  224 ,  221 ,  151 ,  72 ,  64 ,  93 ,  115 ,  72 ,  192 ,  145 ,  95 ,  72 ,  96 ,  106 ,  129 ,  72 ,  160 ,  33 ,  164 ,  72 ,  160 ,  240 ,  143 ,  72 ,  96 ,  122 ,  147 ,  72 ,  32 ,  73 ,  158 ,  72 ,  160 ,  159 ,  139 ,  72]
    
    var data = new Uint8Array(lst);
    
    let str = Buffer.from(data).toString('base64');
    console.log(str); 
    
    const floatValue =new DataView(data.buffer).getFloat64(0);
    console.log(floatValue) 
    
    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); 
    

    结果如下:

    str

    CgExCgEyCgEzCgE0CgE1CgE2CgE3CgE4CgE5CgIxMAoCMTEKAjEyCgIxMwoCMTQKAjE1CgIxNgoCMTcKAjE4CgIxOQoCMjAKAjIxCgIyMgoCMjMKAjI0EmkKBXB2X2VxEmAA9NZHAJBASIDtW0gAom5IgIqCSIAIMEgA7PxHgNHNR8BRAEiAvf1HgJwCSMBKA0iADYBIYOqWSMAxoUjg3ZdIQF1zSMCRX0hgaoFIoCGkSKDwj0hgepNIIEmeSKCfi0g=
    

    浮点值

    1.7470648220442632e-260
    

    json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24i
    pv_eq`
    

    很遗憾,我还没有得到可以解释的数据。

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      • 2020-09-16
      相关资源
      最近更新 更多