刚学Nodejs,学写采集。为什么踩着踩着,socket 就hang up了。是代码原因还是什么原因
刚学Nodejs,学写采集。为什么踩着踩着,socket 就hang up了。是代码原因还是什么原因
用的needle, 学着采集baidu图片。设定采集2000张。但是程序运行一会后就会socket hang up。请问这是代码的问题还是什么啊.
当在使用 Node.js 进行网络请求时,如果遇到 socket hang up
错误,这通常意味着连接被远程服务器关闭或超时。这种情况可能由多种因素引起,包括但不限于网络问题、服务器限制、代码实现不当等。
下面是一个简单的示例,演示如何使用 needle
库进行图片采集,并讨论可能导致 socket hang up
的原因以及如何优化代码:
示例代码
const needle = require('needle');
const fs = require('fs');
const url = 'https://www.baidu.com/s?wd=example&tn=baiduimage';
let count = 0;
const maxImages = 2000;
function downloadImage(url) {
needle.get(url, { follow_max: 5 }, (err, resp) => {
if (err) {
console.error(err);
return;
}
if (resp.statusCode === 200) {
const filename = `image-${count}.jpg`;
fs.writeFileSync(filename, resp.body);
console.log(`Downloaded image ${filename}`);
count++;
if (count < maxImages) {
// 递归调用以下载更多图片
downloadImage(url);
}
} else {
console.error(`Failed to download image. Status code: ${resp.statusCode}`);
}
});
}
downloadImage(url);
可能的原因及解决方法
-
超时设置不合理:
- 确保针对于每个请求设置了合理的超时时间。例如,在
needle.get
中增加超时时间参数。
needle.get(url, { timeout: 10000 }, (err, resp) => {...});
- 确保针对于每个请求设置了合理的超时时间。例如,在
-
并发请求过多:
- 如果同时发起大量请求,可能会导致服务器限制访问或网络拥塞。可以考虑使用队列机制或限制并发请求的数量。
-
资源泄漏:
- 确保每次请求完成后正确处理响应和错误,避免资源泄漏。上述示例中已经包含了错误处理逻辑。
-
服务器限制:
- 某些网站可能对爬虫有严格的限制。可以尝试添加 HTTP 头来模拟浏览器访问,或者检查是否有 CAPTCHA 验证等限制。
通过以上方式,你可以更好地诊断并解决 socket hang up
问题。
刚写了个爬虫,考察过needle,不过decode的处理不够好,而且缺乏任务调度,不能很好的满足我的需求,因为我主要就是需要任务调度,不然很快就会被识别出是爬虫而被禁止访问,所以自己用request+async+iconv-lite+cheerio简单写了个
分享下? 似乎这个项目也用到了iconv-lite
由于刚学,所以关于任务调度还不是很清楚。不过decode对于我够用了,改了一下,一般的gbk,big5都行。
var max = 10;
http.globalAgent.maxSockets = (max || 5);
你不会一憋气采集2000张图片吧? 我采集的时候把任务分开,隔几秒采集一些。让人家服务器也缓缓气。
你是指百度的服务器?我没有抓百度。
从你的描述来看,出现 socket hang up
错误通常意味着网络连接被提前关闭了。这可能是由于多个原因导致的,比如网络问题、服务器端主动关闭连接、请求超时、资源耗尽等。为了更好地定位问题,我们可以先看看常见的排查方法,并提供一个简单的示例来帮助理解如何处理。
排查方法
- 检查网络稳定性:确保网络连接稳定。
- 设置超时时间:为请求设置合理的超时时间,避免长时间等待响应。
- 错误处理:增加错误处理逻辑,以便更好地捕获异常情况。
- 并发限制:如果同时发送大量请求,可能会导致服务器限制或超时,适当控制并发数。
- 服务器限制:某些服务器可能对单个客户端的请求频率有限制,可以尝试增加重试机制或延时。
示例代码
以下是一个简单的使用 needle
模块采集图片的例子,并增加了错误处理和超时设置:
const needle = require('needle');
async function downloadImages() {
const urls = ['http://example.com/image1.jpg', 'http://example.com/image2.jpg']; // 假设这是你要下载的图片URL列表
const maxRetries = 3; // 最大重试次数
const timeout = 5000; // 超时时间(毫秒)
for (let i = 0; i < urls.length; i++) {
let retries = 0;
while (retries <= maxRetries) {
try {
const response = await needle('get', urls[i], { timeout });
if (response.statusCode === 200) {
// 处理成功下载的情况
console.log(`成功下载 ${urls[i]}`);
break; // 成功则跳出循环
} else {
console.error(`请求失败,状态码:${response.statusCode}`);
}
} catch (error) {
console.error(`第 ${i + 1} 张图片下载失败,重试中...`, error.message);
retries++;
}
}
if (retries > maxRetries) {
console.error(`超过最大重试次数,放弃下载 ${urls[i]}`);
}
}
}
downloadImages().catch(console.error);
解释
- needle: 用于HTTP请求的模块。
- timeout: 设置超时时间,防止请求长时间无响应。
- try-catch: 捕获请求过程中的异常,进行错误处理和重试。
- maxRetries: 设定最大重试次数,避免无限重试。
通过上述方法,你可以更好地定位和解决 socket hang up
问题。希望这能帮到你!