Puppeteer爬蟲初探

今天發現了一個很好玩的node庫,Puppeteer,準備玩一下。先來看看官方的介紹。html

Puppeteer 是一個 Node 庫,它提供了一個高級 API 來經過 DevTools 協議控制 Chromium 或 Chrome。換句話說,它最大的特色就是它的操做Dom能夠徹底在內存中進行模擬既在V8引擎中處理而不打開瀏覽器。前端

那麼 Puppeteer能夠用來作什麼?node

  • 能夠生成頁面PDF文件;
  • 抓取 SPA(單頁應用)並生成預渲染內容(即「SSR」(服務器端渲染));
  • 自動提交表單,進行 UI 測試,鍵盤輸入等;
  • 建立一個時時更新的自動化測試環境。 使用最新的 JavaScript; 和瀏覽器功能直接在最新版本的Chrome中執行測試;
  • 捕獲網站的 timeline trace,用來幫助分析性能問題;
  • 測試瀏覽器擴展;

這麼多優秀的功能,簡直是前端神器。jquery

Puppeteer 由於須要使用 async / await,因此儘可能保證Node的版本在v7.6.0以上。git

本文主要拿它的爬蟲功能玩一玩。github

--------------------—--------------僞裝分隔符--------------------------------------------ajax

安裝很簡單,一句話搞定: npm i puppeteer or yarn add puppeteerexpress

安裝好之後,寫個例子玩一下:npm

const puppeteer = require('puppeteer');
(async() => {
    // 配置瀏覽器
    const browser = await puppeteer.launch({headless: true});
    
    // 打開一個新頁面
    const page = await browser.newPage();
    
    // 進入頁面
    await page.goto('https://juejin.im/timeline');

    // 截個圖看一下
    await page.screenshot({
        path: 'image.png',
        fullPage: true,
     });
})();
複製代碼

沒錯,咱們準備爬一下掘金的數據。看一下剛纔的截圖瀏覽器

很神奇有木有,幾行代碼就實現了長截圖。

進去了網址,接着玩一下它的輸入框。

// 進入頁面
await page.goto('https://juejin.im/timeline');

// 找到輸入框的class
await page.type('.search-input', "puppeteer");

// 按下enter鍵
await page.keyboard.press('Enter');

// 等兩秒鐘,模擬一下用戶輸入,也要登一下數據刷出來
await page.waitFor(2000);

// 再截個圖看一下
await page.screenshot({
    path: 'image.png',
    fullPage: true,
 });
複製代碼

查到數據了!!也就是僅僅幾行代碼,就實現了搜索。能夠腦補一下,模擬用戶登陸哦~~~

截圖和操做輸入框咱們都玩過了,那咱們就能夠作一個簡單的小東西,實現一個頁面,在搜索框裏面輸入關鍵字,查找出掘金的相關文章。

正常操做,

安裝一下express yarn add express

建立index.js

const express = require('express');
const app = express();
const ejs = require('ejs');
const main = require('./puppeteer');

app.set('view engine','ejs');

app.use('/index', (req, res) => res.render('index'));

app.use('/search', async(req, res) => {
    const { value, more } = req.query;
    const list = await main(value, more);
    res.send(list);
});

app.listen(3000, () => console.log('Example app listening on port 3000!'));
複製代碼

咱們用到了ejs模板,有時間的童鞋能夠寫一個漂亮美觀的前端頁面~

在同級目錄下建立views目錄,而後再建立index.ejs

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>node爬蟲</title>
</head>
<body>
<ul class="list"></ul>
<input type="text" class="input_value">
<span class="search" style="cursor: pointer; color: blue;">Search</span>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
    $('.search').click(() => {
        $.ajax({
            type: 'GET',
            url: '/search',
            data: {value: $('.input_value').val()},
            success: res => $('ul').html(res.reduce((total, item) => total + `<li><a target="_blank" href="${item.href}">${item.title}</a></li>`, ''))
        });
    });
</script>
</html>
複製代碼

接着建立關鍵爬蟲代碼:

const puppeteer = require('puppeteer');

async function main(value) {
    // 配置瀏覽器
    const browser = await puppeteer.launch({headless: true});

    // 建立一個新頁面
    const page = await browser.newPage();

    // 進入網址
    await page.goto('https://juejin.im/timeline');

    // 找到搜索框
    await page.type('.search-input', value);

    // 點擊搜索
    await page.keyboard.press('Enter');

    // 等待文章列表出來
    await page.waitForSelector('.main-list');

    // 截圖看一下
    await page.screenshot({
        path: 'image.png',
        fullPage: true,
    });

    // 找一下文章容器
    const list = await page.$('.main-list');

    // 組合一下文章標題和連接
    const result = await list.$$eval('.entry-link', e => e.map(v => ({
        href: v.href,
        title: v.querySelector('.title').firstChild.innerText
    })));

    return result;
}

module.exports = main;
複製代碼

就建立三個文件,node index.js一下,看看效果~ (界面略醜)

好像少了點,再爬多一點, 把滾動條往下滑到3000的位置,試一下:

// 等待文章列表出來
await page.waitForSelector('.main-list');

// 把滾動條滾動到指定位置
await page.evaluate(() => window.scrollTo(0, 3000));

// 等待時間根據滾動條的位置要增長,否則來不及反應
await page.waitFor(2000);
複製代碼

沒截全,而後腦補一下,是否是能夠用本身寫的爬蟲去爬本身的爬蟲,來搞個長截圖~(我就不試了,留給大家~)

好了,Puppeteer的確很強大,也很好玩,你們有興趣的話,能夠用它來爬一些本身感興趣的網站。~

最後附上所有代碼地址: github

相關文章
相關標籤/搜索