概要
Puppeteerを使用してヘッドレスブラウザとしてウェブスクレイピングを行う時に、個人的に詰まった点のメモです。
前提
Mac OS v10.15.2(19C57)
VSCode 1.41.1
node v12.14.1
Puppeteer 2.1.0
その1 コンソール出力ができない
問題
page.evaluateを使うことで、ページ読み込み後にブラウザ内で任意のスクリプトを実行してHTMLの解析などが可能ですが、デバッグ用にconsoleを仕込んでも何も表示されません。
// 初期化処理constbrowser=awaitpuppeteer.launch({headless:true,args:['--no-sandbox','--disable-setuid-sandbox']});constpage=awaitbrowser.newPage();// 指定のURLのページを開くawaitpage.goto('https://hoge.hoge.hoge');// ブラウザ内でスクリプトを実行constresult=awaitpage.evaluate(()=>{// ここでコンソールを出力しても何も表示されないconsole.log('eval start');// do something});
解決策
pageに対して、consoleイベントを予め登録し、イベント呼び出し処理内でconsoleで書き込みを行います。
page.evaluate内でconsoleを実行するとこのイベントが発火されてconsole出力がされるようになります。
constpage=awaitbrowser.newPage();// コンソールイベントを登録page.on('console',msg=>{for(leti=0;i<msg._args.length;++i)console.log(`${i}: ${msg._args[i]}`);});// 指定のURLのページを開くawaitpage.goto('https://hoge.hoge.hoge');// ブラウザ内でスクリプトを実行constresult=awaitpage.evaluate(()=>{console.log('eval start');// do something});
その2 querySelectorAllで取り出した結果が空のオブジェクトになる
問題
page.evaluate内でquerySelectorを使ってHTML要素を出力しようとするが、正しく値が取れない。
constresult=awaitpage.evaluate(()=>{constdataList=[];// hogeクラスタグ配下のaタグを全て取得constnodeList=document.querySelectorAll('.hoge > a');// 内部のhtmlを出力nodeList.forEach(_node=>{dataList.push(_node.innerText);});returndataList;});// 出力は空文字になる ["", "", ""]console.log(result);
解決策
querySelectorAllで取り出した値は配列になっていない為、Array.fromで配列に変換した後に列挙を行う。
constresult=awaitpage.evaluate(()=>{constdataList=[];// Array.fromで配列に変換constnodeList=Array.from(document.querySelectorAll('.hoge > a'));// 内部のhtmlを出力nodeList.forEach(_node=>{dataList.push(_node.innerText);});returndataList;});console.log(result);
最後に
個人的にPuppeteer使用中にはまった点を書きました。
Puppeteer自体は直感的で便利なのですが、思いがけないところではまって時間を使ってしまいしました。
(マニュアル等をしっかり読まず使えしまう事の弊害かもしれませんが。)