【问题标题】:request nodejs gets unreadable data请求nodejs获取不可读的数据
【发布时间】:2019-12-10 00:43:09
【问题描述】:

我正在尝试使用 node.js 上的库请求来抓取 html。响应代码是 200,我得到的数据是不可读的。这是我的代码:

var request = require("request");

const options = {
  uri: 'https://www.wikipedia.org',
  encoding: 'utf-8',
  headers: {
    "Accept": "text/html,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3", 
    "charset": "utf-8",
    "Accept-Encoding": "gzip, deflate, br", 
    "Accept-Language": "en-US,en;q=0.9", 
    "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36"
    }
};


request(options, function(error, response, body) {
  console.log(body);

});

如您所见,我发送了对 html 和 utf-8 的请求,但得到了一个大字符串,如 f��j���+����x��,�G�Y�l

我的节点版本是v8.10.0,请求版本是2.88.0。

代码有问题还是我遗漏了什么??

任何解决此问题的提示将不胜感激。

【问题讨论】:

    标签: node.js utf-8 request scrape


    【解决方案1】:

    更新答案:

    回应您的最新帖子:

    它不适用于 Amazon 的原因是响应是 gzipped.。为了解压缩 gzip 响应,您只需将 gzip: true 添加到您正在使用的 options 对象中。这适用于亚马逊和维基百科:

    const request = require('request');
    
    const options = {
        uri: "https://www.amazon.com",
        gzip: true
    }
    
    request(options, function(error, response, body) {
        if (error) throw error;
    
        console.log(body);
    });
    

    最后,如果您想像这样抓取网页,最好使用网络抓取框架,例如 Puppeteer,因为它是为网页抓取而构建的。

    请参阅 here 获取 Puppeteer GitHub。



    原答案:

    由于您只是从主页抓取 HTML,因此您不必指定 charset、encoding 或 Accept-Encoding..

    const request = require('request');
    
    const options = {
        uri: 'https://www.wikipedia.org',
        //encoding: 'utf-8',
        headers: {
            "Accept": "text/html,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
            //"charset": "utf-8",
            //"Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "en-US,en;q=0.9",
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/78.0.3904.108 Chrome/78.0.3904.108 Safari/537.36"
        }
    };
    
    request(options, function (error, response, body) {
        if (error) throw error
    
        console.log(body);
    });
    

    更进一步...在这种情况下,您根本不需要指定标题...

    const request = require('request');
    
    request('https://www.wikipedia.org', function (error, response, body) {
        if (error) throw error
    
        console.log(body);
    });
    

    【讨论】:

      【解决方案2】:

      谢谢你的回复,当我用它来维基百科页面正常工作时,但是当我用它来抓取另一个像亚马逊这样的网站时,得到了同样糟糕的结果

      const request = require('request');
      
      request('https://www.amazon.com', function (error, response, body) {
          if (error) throw error
      
          console.log(body);
      });
      

      【讨论】:

      • 我已经用解决方案更新了我的答案。请让我知道这是否适合您。
      • 不适合我,结果相同:�N_��#������>�V ZLT�Յ�"����U���������� &|�1&>>^Hs)�a]]�Q�V�Vn�in���������.�e�FN!Φ���ف�y9�FF�F�A� .
      • 你正在使用这个options 对象? const options = { uri: "https://www.amazon.com", gzip: true } - 这是一个在线Node.js 环境.. 它在这里工作得很好,在我的机器上也是如此.. repl.it/repls/RelevantStrictGigabyte
      • 谢谢您,链接中的代码在链接中可以正常工作,但在我的电脑中不能正常工作。这让我觉得问题出在我的电脑上。我在另一台使用 centos 7 的计算机上再次运行代码(第一个运行 ubuntu 18.04)并且它工作正常,这意味着版本或安装有问题。我要重新安装所有,看看它是否能解决这个问题。非常感谢您的帮助。
      猜你喜欢
      • 1970-01-01
      • 2015-06-28
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 2018-04-06
      • 2021-12-12
      相关资源
      最近更新 更多