抓取远程的网站出现错误(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 客户端库如 axios
或 node-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);
}
});
解释
- axios:使用
axios
库替代原生的http
模块,因为axios
提供了更好的错误处理机制。 - headers:设置请求头以模拟浏览器行为。
- maxRedirects:设置最大重定向次数,防止无限重定向。
- timeout:设置请求超时时间,防止长时间等待。
- 错误处理:通过
.catch
方法捕获并处理不同类型的错误。
这样处理后,即使发生网络错误或服务器端断开连接,程序也不会崩溃,而是能够优雅地处理错误并输出相关信息。
need res.on(‘error’, callback)
从你提供的代码和错误信息来看,问题出在HTTP请求过程中连接被远程服务器重置了。这通常是由于以下几个原因造成的:
- 字符编码问题:
gb2312
编码可能不适用于所有页面,某些页面可能使用其他编码格式。 - 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);
});
关键改进点:
- 使用
https
模块而不是http
,因为目标站点可能只支持 HTTPS。 - 在接收数据时使用
utf8
编码,这样可以避免因编码问题导致的数据读取错误。 - 添加了错误处理逻辑 (
res.on('error', ...)
和https.get(...).on('error', ...)
), 这样可以在出现网络问题时捕获并打印错误信息,便于调试。
通过这些改进,你可以更好地理解问题所在,并找到解决方案。