UNPKG

n8n-nodes-web-crawler

Version:

Node tùy chỉnh cho n8n để cào dữ liệu từ trang web, trích xuất nội dung và hình ảnh

228 lines 9.73 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.execute = execute; const axios_1 = __importDefault(require("axios")); const cheerio = __importStar(require("cheerio")); const imageUtils_1 = require("../utils/imageUtils"); const https_proxy_agent_1 = require("https-proxy-agent"); const http_proxy_agent_1 = require("http-proxy-agent"); async function execute(keyword, maxImages, minImageSize = 0, filterBySize = false, useProxies = false, proxyList = '', requestTimeout = 30000) { // Phân tích danh sách proxy nếu được cung cấp let proxies = []; if (useProxies && proxyList) { proxies = proxyList.split(',').map(proxy => proxy.trim()).filter(proxy => proxy.length > 0); } // Hàm chọn proxy ngẫu nhiên từ danh sách const getRandomProxy = () => { if (proxies.length === 0) return undefined; return proxies[Math.floor(Math.random() * proxies.length)]; }; // Chuẩn bị URL tìm kiếm Google, thêm tbm=isch để tìm kiếm ảnh const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(keyword)}&tbm=isch`; // Thiết lập User-Agent để tránh bị chặn const headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Referer': 'https://www.google.com/' }; // Thiết lập config cho axios const axiosConfig = { headers, timeout: requestTimeout }; // Chọn proxy ngẫu nhiên cho request tìm kiếm const currentProxy = getRandomProxy(); // Thêm cấu hình proxy nếu được chọn if (useProxies && currentProxy) { if (currentProxy.startsWith('https://')) { axiosConfig.httpsAgent = new https_proxy_agent_1.HttpsProxyAgent(currentProxy); } else { axiosConfig.httpAgent = new http_proxy_agent_1.HttpProxyAgent(currentProxy); } } // Mảng lưu URL ảnh đã tìm thấy const imageUrls = []; const skippedImages = { small: 0, error: 0, timeout: 0 }; try { // Gửi yêu cầu HTTP const response = await axios_1.default.get(searchUrl, axiosConfig); const html = response.data; const $ = cheerio.load(html); // Trích xuất URL ảnh từ kết quả tìm kiếm $('img').each((_, element) => { const src = $(element).attr('src') || $(element).attr('data-src'); if (src && !src.includes('data:image') && !imageUrls.includes(src)) { imageUrls.push(src); } }); $('[data-src]').each((_, element) => { const src = $(element).attr('data-src'); if (src && !imageUrls.includes(src)) { imageUrls.push(src); } }); $('script').each((_, element) => { const scriptContent = $(element).html(); if (scriptContent) { const matches = scriptContent.match(/(https?:\/\/[^"'\s]+\.(?:jpg|jpeg|png|gif|webp))/g); if (matches) { for (const match of matches) { if (!imageUrls.includes(match)) { imageUrls.push(match); } } } } }); // Lọc và xử lý các URL ảnh tìm được const processedImages = []; const processedImagesInfo = []; // Giới hạn số lượng ảnh xử lý const imagesToProcess = imageUrls.slice(0, Math.min(maxImages * 3, 30)); // Promise cho các tiến trình xử lý ảnh const imagePromises = imagesToProcess.map(async (imageUrl, index) => { try { const imageProxy = getRandomProxy(); if (filterBySize && minImageSize > 0) { const dimensions = await (0, imageUtils_1.getImageSize)(imageUrl, useProxies ? imageProxy : undefined, requestTimeout); if (dimensions.timeout) { skippedImages.timeout++; return null; } if ((dimensions.width && dimensions.width >= minImageSize) || (dimensions.height && dimensions.height >= minImageSize)) { return { url: imageUrl, width: dimensions.width, height: dimensions.height, index }; } else { skippedImages.small++; return null; } } else { return { url: imageUrl, index }; } } catch (error) { skippedImages.error++; return null; } }); // Xử lý song song tất cả các ảnh let processedResults = []; try { const timeoutController = new AbortController(); const timeoutId = setTimeout(() => timeoutController.abort(), requestTimeout); const results = await Promise.allSettled(imagePromises); clearTimeout(timeoutId); processedResults = results.map(result => { if (result.status === 'fulfilled' && result.value !== null) { return result.value; } return null; }); } catch (error) { console.error('Lỗi khi xử lý tất cả ảnh:', error); } // Lọc bỏ các kết quả null và sắp xếp lại theo vị trí ban đầu const validResults = processedResults .filter(result => result !== null) .sort((a, b) => ((a === null || a === void 0 ? void 0 : a.index) || 0) - ((b === null || b === void 0 ? void 0 : b.index) || 0)); // Lấy số lượng ảnh cần thiết const limitedResults = validResults.slice(0, maxImages); // Chuyển kết quả vào mảng kết quả cuối cùng limitedResults.forEach(result => { processedImages.push(result.url); processedImagesInfo.push({ url: result.url, width: result.width, height: result.height }); }); // Chuẩn bị dữ liệu đầu ra return { json: { operation: 'googleImageSearch', keyword, imageCount: processedImages.length, requestedCount: maxImages, imageUrls: processedImages, imagesInfo: processedImagesInfo, proxyUsed: useProxies && currentProxy ? 'yes' : 'no', filterDetails: { filtered: filterBySize, minImageSize: filterBySize ? minImageSize : undefined, totalFound: imageUrls.length, processedCount: processedImages.length, skipped: skippedImages } }, }; } catch (error) { return { json: { operation: 'googleImageSearch', keyword, imageCount: 0, requestedCount: maxImages, imageUrls: [], imagesInfo: [], proxyUsed: useProxies && currentProxy ? 'yes' : 'no', error: error instanceof Error ? error.message : 'Lỗi không xác định', filterDetails: { filtered: filterBySize, minImageSize: filterBySize ? minImageSize : undefined, totalFound: 0, processedCount: 0, searchFailed: true } }, }; } } //# sourceMappingURL=googleImageSearch.js.map