كيفية إنشاء مكشطة موقع ويب باستخدام وظائف Puppeteer وFirebase

لنقم بإنشاء أداة استخراج بسيطة لموقع الويب تقوم بتنزيل محتوى صفحة الويب واستخراج محتوى الصفحة. في هذا المثال سوف نستخدم New York Times
الموقع كمصدر للمحتوى. ستقوم أداة الكشط باستخراج أهم 10 عناوين أخبار على الصفحة وعرضها على صفحة الويب. تتم عملية الكشط باستخدام متصفح Puppeteer بدون رأس ويتم نشر تطبيق الويب على وظائف Firebase.
1. تهيئة وظيفة Firebase
بافتراض أنك قمت بالفعل بإنشاء مشروع Firebase، يمكنك تهيئة وظائف Firebase في بيئة محلية عن طريق تشغيل الأمر التالي:
mkdir scraper
cd scraper
npx firebase init functions
cd functions
npm install puppeteer
اتبع المطالبات لتهيئة المشروع. نقوم أيضًا بتثبيت حزمة Puppeteer من NPM لاستخدام متصفح Puppeteer بدون رأس.
2. قم بإنشاء تطبيق Node.js
إنشاء جديد pptr.js
ملف في مجلد الوظائف الذي سيحتوي على رمز التطبيق لكشط محتوى الصفحة. سيقوم البرنامج النصي بتنزيل محتوى HTML للصفحة فقط ويحظر جميع الصور وأوراق الأنماط ومقاطع الفيديو والخطوط لتقليل مقدار الوقت المستغرق لتنزيل الصفحة.
نحن نستخدم تعبير XPath لتحديد العناوين الرئيسية على الصفحة المضمنة أسفل h3
علامة. يمكنك استخدام أدوات Chrome Dev للعثور على مسار XPath للعناوين الرئيسية.
const puppeteer = require('puppeteer');
const scrapeWebsite = async () => {
let stories = [];
const browser = await puppeteer.launch({
headless: true,
timeout: 20000,
ignoreHTTPSErrors: true,
slowMo: 0,
args: [
'--disable-gpu',
'--disable-dev-shm-usage',
'--disable-setuid-sandbox',
'--no-first-run',
'--no-sandbox',
'--no-zygote',
'--window-size=1280,720'
]
});
try {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
// Block images, videos, fonts from downloading
await page.setRequestInterception(true);
page.on('request', (interceptedRequest) => {
const blockResources = ['script', 'stylesheet', 'image', 'media', 'font'];
if (blockResources.includes(interceptedRequest.resourceType())) {
interceptedRequest.abort();
} else {
interceptedRequest.continue();
}
});
// Change the user agent of the scraper
await page.setUserAgent(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36'
);
await page.goto('https://www.nytimes.com/', {
waitUntil: 'domcontentloaded'
});
const storySelector = 'section.story-wrapper h3';
// Only get the top 10 headlines
stories = await page.$$eval(storySelector, (divs) =>
divs.slice(0, 10).map((div, index) => `${index + 1}. ${div.innerText}`)
);
} catch (error) {
console.log(error);
} finally {
if (browser) {
await browser.close();
}
}
return stories;
};
module.exports = scrapeWebsite;
3. اكتب وظيفة Firebase
داخل index.js
الملف، قم باستيراد وظيفة الكشط وتصديرها كوظيفة Firebase. نكتب أيضًا وظيفة مجدولة سيتم تشغيلها يوميًا وستستدعي وظيفة الكشط.
من المهم زيادة ذاكرة الوظيفة وحدود المهلة نظرًا لأن Chrome مع Puppeteer يعد موردًا ثقيلًا.
// index.js
const functions = require('firebase-functions');
const scrapeWebsite = require('./pptr');
exports.scrape = functions
.runWith({
timeoutSeconds: 120,
memory: '512MB' || '2GB'
})
.region('us-central1')
.https.onRequest(async (req, res) => {
const stories = await scrapeWebsite();
res.type('html').send(stories.join('<br>'));
});
exports.scrapingSchedule = functions.pubsub
.schedule('09:00')
.timeZone('America/New_York')
.onRun(async (context) => {
const stories = await scrapeWebsite();
console.log('The NYT headlines are scraped every day at 9 AM EST', stories);
return null;
});
4. قم بنشر الوظيفة
إذا كنت ترغب في اختبار الوظيفة محليًا، فيمكنك تشغيل npm run serve
الأمر وانتقل إلى نقطة نهاية الوظيفة على المضيف المحلي. عندما تكون جاهزًا لنشر الوظيفة على السحابة، يكون الأمر هو npm run deploy
.
5. اختبر الوظيفة المجدولة
إذا كنت ترغب في اختبار الوظيفة المجدولة محليًا، فيمكنك تشغيل الأمر npm run shell
لفتح غلاف تفاعلي لاستدعاء الوظائف يدويًا باستخدام بيانات الاختبار. هنا اكتب اسم الوظيفة scrapingSchedule()
واضغط على Enter للحصول على مخرجات الوظيفة.