用Puppeteer爬本身想偷的貓,推翻閏土統治掘金的時代!

Puppeteer爬本身想偷的貓

畢設作的太累,就想寫點小玩具。平時很喜歡雲吸貓,就寫了個小爬蟲,天天爬點貓咪圖片增長點動力,這可比程序員鼓勵師給勁多了(滑稽)!javascript

預熱

PuppeteerGoogle Chrome 團隊官方的無界面(Headless)Chrome 工具,它是一個 Node 庫,提供了一個高級的 API 來控制 DevTools協議上的無頭版 Chrome 。也能夠配置爲使用完整(非無頭)的 ChromeChrome 素來在瀏覽器界穩執牛耳,所以,Chrome Headless 必將成爲 web 應用自動化測試的行業標杆。使用 Puppeteer,至關於同時具備 LinuxChrome 雙端的操做能力,應用場景可謂很是之多。此倉庫的創建,便是嘗試各類折騰使用 GoogleChrome Puppeteer;以期在好玩的同時,學到更多有意思的操做。html

您能夠在瀏覽器中手動完成的大部分事情均可以使用 Puppeteer 完成!你能夠從如下幾個示例開始:java

  • 生成頁面的截圖和PDF。
  • 抓取SPA並生成預先呈現的內容(即「SSR」)。
  • 從網站抓取你須要的內容。
  • 自動錶單提交,UI測試,鍵盤輸入等。
  • 建立一個最新的自動化測試環境。使用最新的JavaScript和瀏覽器功能,直接在最新版本的Chrome中運行測試。
  • 捕獲您的網站的時間線跟蹤,以幫助診斷性能問題。

瞭解更多戳這裏node

正題

使用 Puppeteer 獲取想要的元素

由第一部分能夠知道 Puppeteer 能夠模擬用戶的各類操做,因此咱們想瀏覽「貓片」的第一步就是打開瀏覽器啦!git

1. 打開瀏覽器

const options = {
  // 若是使用headless字段會啓用可視化模式,也就是會啓動Chrome瀏覽器,而且會有頭部地址欄等工具
  // headless: false,
  executablePath: getNPMConfig('chrome')
};
const browser = await Puppeteer.launch(options);
複製代碼

2. 建立一個Tab

const page = await browser.newPage();
複製代碼

3. 輸入「貓片」地址

// 這裏以花花與三貓catlive爲例
await page.goto('https://space.bilibili.com/9008159/dynamic');
複製代碼

4. 重頭戲:獲取Dom元素

因爲是動態網頁,若是使用 JSDom 來獲取 DOM 元素頗有可能會出錯。這也就是咱們爲何選擇 Puppeteer 的緣由,使用 PuppeteerwaitForSelector方法能夠等指定 DOM 元素加載完畢後再獲取。程序員

下面咱們來看一下咱們須要什麼 DOM 元素中的內容:github

能夠看到,動態中的「貓片」是在 .zoom-list 的列表內,包含 .zoom-list 的最外層的父元素是 .s-space,而且每一個圖片的 class 都爲 .img-content,最後照片並非經過 <img />href 屬性進行設置的,而是經過 background-image 來設置的。這樣咱們就能夠下手「偷貓」啦!web

// 最好用比較外層的元素來斷定是否加載完成,由於若是用比較內層的元素來斷定的話,若是超過Puppeteer的斷定時間(能夠本身設定)那麼就會報錯
await page.waitForSelector('.s-space .zoom-list');
// $$eval:第一個參數爲選擇器:選擇要獲取的DOM元素;第二個參數爲回調函數:對獲取的DOM元素的操做
const content = await page.$$eval('.s-space .zoom-list .card',
    items =>
        items.map(
            item =>
                item
                    .querySelector('.img-content')
                    .style.backgroundImage.split('"')[1]
        )
    );
複製代碼

上圖就是咱們獲取的圖片的路徑啦!撒花~chrome

最後一步,發郵件

發郵件咱們使用 nodemailer,沒有用過的夥伴能夠看一下這篇文章NodeJs使用NodeMailer發郵件。要提一下,nodemailer 必定要依託於服務器才能夠發送HTML樣式(至少我試的是這樣)。咱們只須要對咱們得到的數據進行簡單的操做就能夠啦:瀏覽器

htmlContent = content.reduce((acc, cur) => {
        acc += `<div><img style='height: 100px' src='${cur}' alt='' /></div>`;
        return acc;
    }, '');
// 而後在sendMail的第一個參數options中加入下面字段便可
{
    ...
    html: htmlContent
}
複製代碼

郵件內容以下圖:

你們能夠美化一下樣式,我只作了一個簡單的例子。代碼中沒有實現天天定時爬圖片,你們能夠改進一下,天天爬一些圖片發到本身郵箱吸一吸!畢竟在掘金吸了這麼久閏土了,也該換換口味了 23333

但願你們能勞逸結合,身體第一位!

源碼地址:GitHub 中間遇到點問題(就是被選擇器坑了!!!),感謝水歌的耐心解答,也感謝羣裏其餘大佬的解決方案!

相關文章
相關標籤/搜索