前期準備:
npm puppeteer
import puppeteer from 'puppeteer';
puppeteer文檔
第一步:啟動瀏覽器,跳轉到需要爬取的頁面
const browser = await puppeteer.launch({ headless: false });const page = await browser.newPage();await page.goto(url, { waitUntil: 'networkidle2' });
第二步:打開需要爬取的網頁,按“F12”查看前端的dom,查看我們想獲取的文本信息的父級類名,例如:
第三步,通常列表頁面都有下拉刷新,我們需要寫一個腳本讓頁面下拉刷新
我要爬取的頁面下拉到一定的地步后會有一個“加載更多”按鈕,需要點擊,直到頁面無法滾動,且沒有加載更多按鈕的時候停止,腳本參考如下:
// 定義滾動函數const scrollPage = async () => {const distance = 100000; // 每次滾動的距離const delay = 2000; // 每次滾動后的延遲let previousHeight = await page.evaluate('document.body.scrollHeight');while (true) {await page.evaluate(`window.scrollBy(0, ${distance})`);await new Promise(resolve => setTimeout(resolve, delay));const newHeight = await page.evaluate('document.body.scrollHeight');if (newHeight === previousHeight) {const loadMoreButton = await page.$('.類名1.類名2');//鎖定“加載更多按鈕”if (loadMoreButton) {await loadMoreButton.click();console.log('點擊加載更多結果按鈕');await new Promise(resolve => setTimeout(resolve, delay)); // 等待加載更多內容} else {console.log('已滾動到底部,沒有更多內容加載');break;}}previousHeight = newHeight;}
};await scrollPage();
第四步,封裝成對象并打印
第三步的腳本讓我們把頁面加載到擁有全部數據的狀態,現在需要將第二步收集的類名里的文本封裝成數組
await page.waitForSelector('.卡片父級類名', { timeout: 60000 });//卡片最外層
const info= await page.evaluate(() => {const cardElements = document.querySelectorAll('.卡片父級類名');//獲取所有卡片const arr= [];cardElements.forEach(hotel => {const nameElement = hotel.querySelector('[需要的元素1的屬性]');const priceElement = hotel.querySelector('[需要的元素2的屬性]');const name = nameElement ? nameElement.innerText.trim() : null;const price = priceElement ? priceElement.innerText.trim() : null;if (name || price) {arr.push({ name, price });}});return arr;
});console.log(JSON.stringify(info, null, 2))// 完事關閉瀏覽器
await browser.close();