刚学Nodejs,学写采集。为什么踩着踩着,socket 就hang up了。是代码原因还是什么原因

刚学Nodejs,学写采集。为什么踩着踩着,socket 就hang up了。是代码原因还是什么原因

用的needle, 学着采集baidu图片。设定采集2000张。但是程序运行一会后就会socket hang up。请问这是代码的问题还是什么啊.

8 回复

当在使用 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);

可能的原因及解决方法

  1. 超时设置不合理

    • 确保针对于每个请求设置了合理的超时时间。例如,在 needle.get 中增加超时时间参数。
    needle.get(url, { timeout: 10000 }, (err, resp) => {...});
    
  2. 并发请求过多

    • 如果同时发起大量请求,可能会导致服务器限制访问或网络拥塞。可以考虑使用队列机制或限制并发请求的数量。
  3. 资源泄漏

    • 确保每次请求完成后正确处理响应和错误,避免资源泄漏。上述示例中已经包含了错误处理逻辑。
  4. 服务器限制

    • 某些网站可能对爬虫有严格的限制。可以尝试添加 HTTP 头来模拟浏览器访问,或者检查是否有 CAPTCHA 验证等限制。

通过以上方式,你可以更好地诊断并解决 socket hang up 问题。


刚写了个爬虫,考察过needle,不过decode的处理不够好,而且缺乏任务调度,不能很好的满足我的需求,因为我主要就是需要任务调度,不然很快就会被识别出是爬虫而被禁止访问,所以自己用request+async+iconv-lite+cheerio简单写了个

分享下? 似乎这个项目也用到了iconv-lite

https://github.com/scottkiss/nodegrass

由于刚学,所以关于任务调度还不是很清楚。不过decode对于我够用了,改了一下,一般的gbk,big5都行。

var max = 10;
http.globalAgent.maxSockets = (max || 5);

http://nodejs.org/api/http.html#http_agent_maxsockets

你不会一憋气采集2000张图片吧? 我采集的时候把任务分开,隔几秒采集一些。让人家服务器也缓缓气。

你是指百度的服务器?我没有抓百度。

从你的描述来看,出现 socket hang up 错误通常意味着网络连接被提前关闭了。这可能是由于多个原因导致的,比如网络问题、服务器端主动关闭连接、请求超时、资源耗尽等。为了更好地定位问题,我们可以先看看常见的排查方法,并提供一个简单的示例来帮助理解如何处理。

排查方法

  1. 检查网络稳定性:确保网络连接稳定。
  2. 设置超时时间:为请求设置合理的超时时间,避免长时间等待响应。
  3. 错误处理:增加错误处理逻辑,以便更好地捕获异常情况。
  4. 并发限制:如果同时发送大量请求,可能会导致服务器限制或超时,适当控制并发数。
  5. 服务器限制:某些服务器可能对单个客户端的请求频率有限制,可以尝试增加重试机制或延时。

示例代码

以下是一个简单的使用 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 问题。希望这能帮到你!

回到顶部