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

250 lines 11.2 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 https_proxy_agent_1 = require("https-proxy-agent"); const http_proxy_agent_1 = require("http-proxy-agent"); /** * Tạo ID ngẫu nhiên cho bài viết */ function generateArticleId() { return `article_${Date.now()}_${Math.floor(Math.random() * 1000)}`; } /** * Lấy bài viết ngẫu nhiên từ trang web */ async function execute(url, articleSelector, titleSelector, linkSelector, contentSelector, fetchFullContent = true, paginationSelector = '', maxPages = 1, 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; const randomIndex = Math.floor(Math.random() * proxies.length); return proxies[randomIndex]; }; try { const pagesUrls = [url]; let currentPageUrl = url; let allArticleElements = []; let pagesVisited = 1; // Cài đặt các tùy chọn mặc định cho request const axiosConfig = () => { const config = { timeout: requestTimeout, 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' } }; // Thêm proxy nếu được yêu cầu if (useProxies) { const proxy = getRandomProxy(); if (proxy) { if (proxy.startsWith('https://')) { config.httpsAgent = new https_proxy_agent_1.HttpsProxyAgent(proxy); } else { config.httpAgent = new http_proxy_agent_1.HttpProxyAgent(proxy); } } } return config; }; // Nếu truy cập nhiều trang, tìm các liên kết phân trang if (paginationSelector && maxPages > 1) { try { const initialPageResponse = await axios_1.default.get(url, axiosConfig()); const $ = cheerio.load(initialPageResponse.data); // Lấy tất cả các phần tử bài viết từ trang đầu tiên const firstPageArticles = $(articleSelector).toArray(); allArticleElements = [...allArticleElements, ...firstPageArticles]; // Tìm các liên kết phân trang const paginationLinks = $(paginationSelector).toArray(); for (const link of paginationLinks) { if (pagesUrls.length >= maxPages) break; const href = $(link).attr('href'); if (href) { // Chuẩn hóa URL let nextPageUrl; if (href.startsWith('http')) { nextPageUrl = href; } else { const baseUrl = new URL(url); nextPageUrl = href.startsWith('/') ? `${baseUrl.protocol}//${baseUrl.host}${href}` : `${baseUrl.protocol}//${baseUrl.host}/${href}`; } // Chỉ thêm nếu URL mới if (!pagesUrls.includes(nextPageUrl)) { pagesUrls.push(nextPageUrl); } } } // Duyệt qua các trang tiếp theo để thu thập bài viết for (let i = 1; i < pagesUrls.length && i < maxPages; i++) { const pageUrl = pagesUrls[i]; try { const pageResponse = await axios_1.default.get(pageUrl, axiosConfig()); const pageHtml = cheerio.load(pageResponse.data); const pageArticles = pageHtml(articleSelector).toArray(); allArticleElements = [...allArticleElements, ...pageArticles]; pagesVisited++; currentPageUrl = pageUrl; } catch (error) { // Bỏ qua lỗi khi truy cập trang, tiếp tục với trang tiếp theo console.error(`Lỗi khi truy cập trang ${pageUrl}:`, error); } } } catch (error) { // Nếu lỗi khi tải trang đầu tiên, quay lại phương pháp mặc định console.error('Lỗi khi tải trang đầu tiên:', error); } } // Nếu không có bài viết nào từ nhiều trang, thử tải trang đầu tiên if (allArticleElements.length === 0) { const response = await axios_1.default.get(url, axiosConfig()); const $ = cheerio.load(response.data); allArticleElements = $(articleSelector).toArray(); pagesVisited = 1; currentPageUrl = url; } // Nếu không tìm thấy bài viết nào if (allArticleElements.length === 0) { return { json: { operation: 'randomArticle', error: `Không tìm thấy bài viết nào với selector "${articleSelector}"`, url, success: false } }; } // Chọn ngẫu nhiên một bài viết const randomIndex = Math.floor(Math.random() * allArticleElements.length); const selectedArticle = allArticleElements[randomIndex]; // Lấy thông tin từ bài viết đã chọn const $ = cheerio.load(selectedArticle); const title = $(titleSelector).text().trim(); const linkElement = $(linkSelector); // Lấy liên kết của bài viết let articleLink = linkElement.attr('href') || ''; // Chuẩn hóa URL nếu là liên kết tương đối if (articleLink && !articleLink.startsWith('http')) { const baseUrl = new URL(url); articleLink = articleLink.startsWith('/') ? `${baseUrl.protocol}//${baseUrl.host}${articleLink}` : `${baseUrl.protocol}//${baseUrl.host}/${articleLink}`; } // Trích xuất nội dung (hoặc lấy nội dung tóm tắt) let content = $(contentSelector).text().trim(); let images = []; // Nếu yêu cầu lấy nội dung đầy đủ, truy cập vào trang bài viết if (fetchFullContent && articleLink) { try { const articleResponse = await axios_1.default.get(articleLink, axiosConfig()); const articlePage = cheerio.load(articleResponse.data); content = articlePage(contentSelector).text().trim(); // Trích xuất các hình ảnh từ nội dung articlePage(`${contentSelector} img`).each((_, img) => { const imgSrc = articlePage(img).attr('src'); if (imgSrc) { // Chuẩn hóa URL hình ảnh let imageUrl = imgSrc; if (!imgSrc.startsWith('http') && !imgSrc.startsWith('data:')) { const baseUrl = new URL(articleLink); imageUrl = imgSrc.startsWith('/') ? `${baseUrl.protocol}//${baseUrl.host}${imgSrc}` : `${baseUrl.protocol}//${baseUrl.host}/${imgSrc}`; } images.push(imageUrl); } }); } catch (error) { console.error('Lỗi khi tải nội dung đầy đủ:', error); } } // Tạo ID duy nhất cho bài viết const articleId = generateArticleId(); // Trả về kết quả return { json: { operation: 'randomArticle', articleId, article: { title, link: articleLink, content, images, pageUrl: currentPageUrl }, message: `Đã lấy bài viết "${title}" từ trang web`, stats: { pagesVisited, totalArticlesFound: allArticleElements.length, proxyUsed: useProxies && proxies.length > 0 ? 'yes' : 'no' } } }; } catch (error) { let errorMessage = 'Lỗi không xác định'; if (error instanceof Error) { errorMessage = error.message; } // Trả về thông báo lỗi return { json: { operation: 'randomArticle', error: errorMessage, url, success: false } }; } } //# sourceMappingURL=randomArticle.js.map