Nodejs 最近做的一个爬虫,功能比较全面
Nodejs 最近做的一个爬虫,功能比较全面
https://github.com/dlutwuwei/CrawlerX 在github上找过一些爬虫,都不带深度遍历,总缺少一些东西,现在做了一个,对请求并发做了控制,可以设置并发数,对不同URL做不同处理,可以设置中文(GBK)的解码,有需要的人看看,有什么需要改进的,欢迎提意见。
2 回复
当然,下面是一个关于 Node.js 爬虫的详细示例,包括并发控制、不同 URL 的处理以及中文解码等功能。
示例代码
const axios = require('axios');
const cheerio = require('cheerio');
const url = require('url');
// 并发控制
const MAX_CONCURRENT_REQUESTS = 5;
let activeRequests = 0;
// 存储已经访问过的 URL 避免重复抓取
const visitedUrls = new Set();
// 需要抓取的初始 URL 列表
const urlsToVisit = [
'http://example.com',
'http://example.org'
];
// 处理不同 URL 的函数
async function handleUrl(urlStr, depth) {
if (visitedUrls.has(urlStr)) return;
visitedUrls.add(urlStr);
try {
const response = await axios.get(urlStr);
const decodedContent = Buffer.from(response.data, 'binary').toString('gbk');
const $ = cheerio.load(decodedContent);
console.log(`Depth ${depth}: ${urlStr}`);
console.log($('title').text());
// 查找并处理所有链接
$('a').each((i, link) => {
const href = $(link).attr('href');
if (href && !visitedUrls.has(href)) {
const absoluteUrl = url.resolve(urlStr, href);
urlsToVisit.push(absoluteUrl);
}
});
} catch (error) {
console.error(`Error fetching ${urlStr}:`, error.message);
}
}
// 控制并发请求
async function processQueue() {
while (urlsToVisit.length > 0) {
while (activeRequests < MAX_CONCURRENT_REQUESTS && urlsToVisit.length > 0) {
const currentUrl = urlsToVisit.shift();
activeRequests++;
handleUrl(currentUrl, 1); // 这里可以根据需求调整深度
}
await new Promise(resolve => setTimeout(resolve, 100)); // 避免过于频繁地检查队列
}
}
processQueue().then(() => console.log('Crawling finished'));
解释
-
并发控制:
- 使用
MAX_CONCURRENT_REQUESTS
来限制同时进行的请求数量。 activeRequests
记录当前正在进行的请求数量,确保不超过设定的最大值。
- 使用
-
避免重复抓取:
- 使用
visitedUrls
集合来记录已经访问过的 URL,防止重复抓取。
- 使用
-
处理不同 URL:
handleUrl
函数负责处理每个 URL,获取页面内容,并使用 Cheerio 解析 HTML。- 对于页面中的每个链接,将其转换为绝对 URL 并加入待访问队列。
-
中文解码:
- 使用
Buffer.from(response.data, 'binary').toString('gbk')
将响应内容从 GBK 编码解码为字符串。
- 使用
-
递归抓取:
- 通过递归调用
handleUrl
函数来处理新的 URL,从而实现深度遍历。
- 通过递归调用
希望这个示例能帮助你理解如何构建一个功能全面的 Node.js 爬虫。如果有任何问题或改进建议,欢迎留言讨论!
根据你的描述,你已经完成了一个较为全面的爬虫项目,并且已经在GitHub上分享了代码。以下是一个简单的示例代码,展示如何使用Node.js进行爬虫开发,并包含一些基本功能如请求并发控制、不同URL的处理以及字符编码支持。
示例代码
const axios = require('axios');
const cheerio = require('cheerio');
// 并发控制队列
const MAX_CONCURRENT_REQUESTS = 5;
let activeRequests = 0;
async function handleRequest(url) {
try {
const response = await axios.get(url, { responseType: 'text' });
const $ = cheerio.load(response.data);
// 处理响应数据
console.log(`Processing ${url}`);
$('a').each((index, element) => {
const link = $(element).attr('href');
if (link && link.startsWith('http')) {
// 将新的URL添加到队列中
addUrlToQueue(link);
}
});
} catch (error) {
console.error(`Error processing ${url}:`, error);
} finally {
// 请求完成后减少活动请求计数
activeRequests--;
}
}
function addUrlToQueue(url) {
// 控制并发数量
while (activeRequests >= MAX_CONCURRENT_REQUESTS) {
// 等待直到有空闲的请求槽位
await new Promise(resolve => setTimeout(resolve, 100));
}
activeRequests++;
handleRequest(url);
}
// 初始URL
addUrlToQueue('https://example.com');
代码解释
- 依赖库:使用
axios
进行HTTP请求,cheerio
解析HTML。 - 并发控制:通过
activeRequests
变量来跟踪当前活跃的请求数量,限制最大并发数为MAX_CONCURRENT_REQUESTS
。 - 请求处理:在
handleRequest
函数中,处理每个请求返回的数据,并提取页面中的链接,递归地将新链接添加到队列中。 - 字符编码支持:在这个例子中没有明确提到字符编码,但可以通过配置
axios
选项来指定所需的字符编码(例如GBK)。
提示
如果你需要进一步增强爬虫的功能,可以考虑加入错误重试机制、异常处理、日志记录、数据库存储等功能。此外,如果目标网站结构复杂或反爬策略严格,建议深入研究网站的HTML结构和服务器响应,以提高爬取效率和成功率。