抓取远程的网站出现错误(Nodejs相关)

抓取远程的网站出现错误(Nodejs相关)

var http = require(‘http’)
var options = {
host:‘ask.39.net’,
path:’/browse/313-2-1.html’,
headers:{
‘User-Agent’:‘Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31’,
‘Referer’:‘http://ask.39.net/browse/313-1-1.html’,
‘Connection’:‘keep-alive’
}
}
http.get(options,function(res){
res.setEncoding(‘gb2312’)
res.on(‘data’,function(data){
console.log(data)
})
})

出现下面的错误

   throw er; // Unhandled 'error' event
              ^
Error: read ECONNRESET
    at errnoException (net.js:883:11)
    at TCP.onread (net.js:539:19)

3 回复

当使用 Node.js 抓取远程网站时,可能会遇到各种网络问题。在你的例子中,错误信息 Error: read ECONNRESET 表明服务器端主动断开了连接。这可能是因为服务器检测到不正常的请求行为、超时或其他网络问题。

为了处理这种情况,可以增加错误处理逻辑,并考虑使用更现代的 HTTP 客户端库如 axiosnode-fetch,这些库提供了更好的错误处理机制。

以下是改进后的代码示例,使用 axios 库来抓取远程网站:

安装 axios

首先需要安装 axios

npm install axios

改进后的代码

const axios = require('axios');

const options = {
    url: 'http://ask.39.net/browse/313-2-1.html',
    method: 'GET',
    responseType: 'text', // 确保响应是文本格式
    headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31',
        'Referer': 'http://ask.39.net/browse/313-1-1.html',
        'Connection': 'keep-alive'
    },
    maxRedirects: 5, // 最大重定向次数
    timeout: 10000, // 请求超时时间,单位为毫秒
};

axios(options)
    .then(response => {
        // 处理成功响应
        console.log(response.data);
    })
    .catch(error => {
        // 处理错误
        if (error.response) {
            // 服务器返回了错误状态码
            console.error('Server returned an error:', error.response.status);
        } else if (error.request) {
            // 请求已发出,但没有收到响应
            console.error('Request failed:', error.request);
        } else {
            // 发生了一些异常
            console.error('Error:', error.message);
        }
    });

解释

  1. axios:使用 axios 库替代原生的 http 模块,因为 axios 提供了更好的错误处理机制。
  2. headers:设置请求头以模拟浏览器行为。
  3. maxRedirects:设置最大重定向次数,防止无限重定向。
  4. timeout:设置请求超时时间,防止长时间等待。
  5. 错误处理:通过 .catch 方法捕获并处理不同类型的错误。

这样处理后,即使发生网络错误或服务器端断开连接,程序也不会崩溃,而是能够优雅地处理错误并输出相关信息。


need res.on(‘error’, callback)

从你提供的代码和错误信息来看,问题出在HTTP请求过程中连接被远程服务器重置了。这通常是由于以下几个原因造成的:

  1. 字符编码问题gb2312 编码可能不适用于所有页面,某些页面可能使用其他编码格式。
  2. URL协议:你的代码中没有指定 HTTP 或 HTTPS 协议,默认为 HTTP。如果目标站点只支持 HTTPS,则需要修改 host 字段。

这里提供一个改进后的示例代码,尝试使用 HTTPS 并添加错误处理逻辑来帮助诊断问题:

var https = require('https');
var options = {
    hostname: 'ask.39.net',
    path: '/browse/313-2-1.html',
    headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31',
        'Referer': 'http://ask.39.net/browse/313-1-1.html',
        'Connection': 'keep-alive'
    }
};

https.get(options, function(res) {
    let data = '';
    res.setEncoding('utf8');  // 尝试使用 UTF-8 编码
    res.on('data', function(chunk) {
        data += chunk;
    });
    res.on('end', function() {
        console.log(data);
    });
}).on('error', function(e) {
    console.error("Got error: " + e.message);
});

关键改进点:

  1. 使用 https 模块而不是 http,因为目标站点可能只支持 HTTPS。
  2. 在接收数据时使用 utf8 编码,这样可以避免因编码问题导致的数据读取错误。
  3. 添加了错误处理逻辑 (res.on('error', ...)https.get(...).on('error', ...)), 这样可以在出现网络问题时捕获并打印错误信息,便于调试。

通过这些改进,你可以更好地理解问题所在,并找到解决方案。

回到顶部