puppeteer すぐ使える取得例

いろんな記事見ても、うーむわからん!取得できん!
となって、うまく動かないことが多かったので、試行錯誤の末とりあえず動いた例をここにおいておきます。

リストが並んでてそこから情報を取り出したい
ということが多いと思いますが、そういったときにだいたい使えると思います。

はてなブックマークの人気エントリーのリストから取り出す

そんな例です。ブックマーク数、タイトル、URLを抜き出して配列にしています。
コンソールに、結合してから出力しています。


const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({ 
        //executablePath: '/usr/bin/chromium-browser',
        args: ['--no-sandbox'],
        //見えるようにfalseにしたけど本番はtrueにしてね
        headless:false
    });

    //配列を作る
    var text = [];
    
    const page = await browser.newPage();
    await page.goto('http://b.hatena.ne.jp/hotentry/all',{ waitUntil: 'domcontentloaded' });
    //await page.waitFor(2000);

    //情報を取り出したい同列に並んでいる要素(liとかが多い)
    const items = await page.$$('#container > div.wrapper > div > div.entrylist-main > section > ul > li > div > div.entrylist-contents-main');

    //取り出したい内容のselectorをなんとかして選ぶ
    const inner1 = await page.$$('#container > div.wrapper > div > div.entrylist-main > section > ul > li > div > div.entrylist-contents-main > h3 > a');
    const inner2 = await page.$$('#container > div.wrapper > div > div.entrylist-main > section > ul > li > div > div.entrylist-contents-main > span > a');
    
    //要素分ループを回す
    for (let i = 0; i < items.length; i++) {
        //取得
        const text1 = await page.evaluate(content => content.innerText, inner1[i]);
        const text2 = await page.evaluate(content => content.innerText, inner2[i]);
        const text3 = await page.evaluate(content => content.href, inner2[i]);
        //配列に追加していく
        text.push( text1 + " 【" + text2 + "】\n" + text3 + "\n"); 
    }

    //配列を全て結合
    text = text.join("");

    //結合した配列を出力
    console.log(text);

    await browser.close();
})();

itemsが並んでる要素。
innerが取り出したい中身です。上記の図でわかるでしょうか。

こういうパターンもありますね。赤が「items」青が「inner」になります。

セレクターをうまく取り出す方法

セレクターがうまく指定できてないことが動かない原因であることが多いです。
デベロッパーツールでセレクターを取得する方法です。

chromeのデベロッパーツールを開き、その要素の上で右クリック。
Copy > Copy selector と選ぶとその場所のセレクターがコピーできます。
どこかにペーストしてください。

#container > div.wrapper > div > div.entrylist-main > section > ul > li:nth-child(1) > div > div.entrylist-contents-main > span > a

こんな感じになります。「何個め」を表す:nth-child はループさせるときに邪魔になるので

#container > div.wrapper > div > div.entrylist-main > section > ul > li > div > div.entrylist-contents-main > span > a

このように少し削除して上記のサンプルでは利用しています。

まとめ

スクレイピングは元サイトに迷惑をかけないようマナーを守ってやりましょう!
訴えられた例もあるので注意してね。 https://ja.wikipedia.org/wiki/%E5%B2%A1%E5%B4%8E%E5%B8%82%E7%AB%8B%E4%B8%AD%E5%A4%AE%E5%9B%B3%E6%9B%B8%E9%A4%A8%E4%BA%8B%E4%BB%B6