基于JavaScript、puppeteer的爬虫

前期准备:

npm puppeteer

import puppeteer from 'puppeteer';

puppeteer文档

第一步:启动浏览器,跳转到需要爬取的页面

javascript 复制代码
const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();

    await page.goto(url, { waitUntil: 'networkidle2' });

第二步:打开需要爬取的网页,按"F12"查看前端的dom,查看我们想获取的文本信息的父级类名,例如:

第三步,通常列表页面都有下拉刷新,我们需要写一个脚本让页面下拉刷新

我要爬取的页面下拉到一定的地步后会有一个"加载更多"按钮,需要点击,直到页面无法滚动,且没有加载更多按钮的时候停止,脚本参考如下:

javascript 复制代码
 // 定义滚动函数
  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();

第四步,封装成对象并打印

第三步的脚本让我们把页面加载到拥有全部数据的状态,现在需要将第二步收集的类名里的文本封装成数组

javascript 复制代码
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();

运行

相关推荐
To_OC2 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
Scott9999HH2 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社3 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海3 小时前
python 列表、元组、集合和字典
开发语言·python
二十雨辰4 小时前
[爬虫]-Urllib
爬虫·python
小林ixn4 小时前
从零到一理解 React 父子组件通信:手写一个 Todo 应用带你彻底搞懂单向数据流
前端·javascript·react.js
萧瑟余晖4 小时前
JDK 26 新特性详解
java·开发语言
马优晨5 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
窝子面6 小时前
手搓最简前后端协作-node
javascript·数据库
人邮异步社区6 小时前
怎么把C语言学到精通?
c语言·开发语言