使用Node.js从URL读取内容

46

我正在尝试使用Node.js从URL中读取内容,但是我似乎只得到了一堆字节。我显然做错了什么,但我不确定是什么。这是我目前的代码:

var http = require('http');

var client = http.createClient(80, "google.com");
request = client.request();
request.on('response', function( res ) {
    res.on('data', function( data ) {
        console.log( data );
    } );
} );
request.end();

任何见解都会非常感激。

4个回答

59

尝试使用客户端的onerror事件查找问题。

var http = require('http');

var options = {
    host: 'google.com',
    path: '/'
}
var request = http.request(options, function (res) {
    var data = '';
    res.on('data', function (chunk) {
        data += chunk;
    });
    res.on('end', function () {
        console.log(data);

    });
});
request.on('error', function (e) {
    console.log(e.message);
});
request.end();

这个例子适用于大多数链接。但是我发现这个URL,https://au.yahoo.com/ 返回了一个数据缓冲区。即使你使用不同类型的编码将其从缓冲区转换为字符串,它也是不可读的。有什么想法吗? - Nick Taras
@NickTaras 看看我的回答是否符合你的需求 ;-p - ttimasdf
看起来是个不错的解决方案。在这种情况下,雅虎使用G-Zip压缩为网站提供服务。在爬取之前需要另一个过程来解压网页。希望这能帮助到有同样问题的人。Ttimasdf,我会运行你的代码示例并尽快回复更具体的信息。 - Nick Taras

27

HTTP和HTTPS:

const getScript = (url) => {
    return new Promise((resolve, reject) => {
        const http      = require('http'),
              https     = require('https');

        let client = http;

        if (url.toString().indexOf("https") === 0) {
            client = https;
        }

        client.get(url, (resp) => {
            let data = '';

            // A chunk of data has been recieved.
            resp.on('data', (chunk) => {
                data += chunk;
            });

            // The whole response has been received. Print out the result.
            resp.on('end', () => {
                resolve(data);
            });

        }).on("error", (err) => {
            reject(err);
        });
    });
};

(async (url) => {
    console.log(await getScript(url));
})('https://sidanmor.com/');

9

数据对象是一组字节的缓冲区。只需调用.toString()即可获取可读的代码:

console.log( data.toString() );

参考文献:Node.js缓冲区


1
另一种选项是 console.log(JSON.stringify(data));。否则,我发现 npm install eyes 对于其 inspector() 功能非常有用。 - Dave

9
@sidanmor的代码略作修改。主要问题是,并非每个网页都是纯ASCII码,用户应该能够手动处理解码(甚至编码成base64)。
function httpGet(url) {
  return new Promise((resolve, reject) => {
    const http = require('http'),
      https = require('https');

    let client = http;

    if (url.toString().indexOf("https") === 0) {
      client = https;
    }

    client.get(url, (resp) => {
      let chunks = [];

      // A chunk of data has been recieved.
      resp.on('data', (chunk) => {
        chunks.push(chunk);
      });

      // The whole response has been received. Print out the result.
      resp.on('end', () => {
        resolve(Buffer.concat(chunks));
      });

    }).on("error", (err) => {
      reject(err);
    });
  });
}

(async(url) => {
  var buf = await httpGet(url);
  console.log(buf.toString('utf-8'));
})('https://httpbin.org/headers');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接