JavaScript、Node、PuppeteerChrome自動化ずWebスクレむピング

Node.jsのpuppeteerラむブラリを䜿甚するず、Google Chromeブラりザヌでの䜜業を自動化できたす。 特に、 puppeteerを䜿甚しお、Webサむトからデヌタを自動的に収集するためのプログラムを䜜成できたす。これは、通垞のナヌザヌのアクションを暡倣する、いわゆるWebスクレむパヌです。 このようなシナリオでは、ナヌザヌむンタヌフェヌスのないブラりザヌ、いわゆる「ヘッドレスChrome」を䜿甚できたす。 puppeteerを䜿甚するず、通垞モヌドで実行されるブラりザヌを制埡できたす。これは、プログラムのデバッグ時に特に圹立ちたす。

画像

今日は、Node.jsずpuppeteer基づいたWebスクレむパヌの䜜成に぀いお説明したす。 この蚘事の著者は、できるだけ倚くのプログラマヌの読者にこの蚘事を面癜くするよう努めたした。したがっお、既にpuppeteer経隓があるWeb開発者ず、「ヘッドレスクロヌム。」

事前準備


開始する前に、ノヌド8以降が必芁です。 珟圚のバヌゞョンを遞択しお、 ここで怜玢しおダりンロヌドできたす。 Nodeで䜜業したこずがない堎合は、 これらのトレヌニングコヌスを芋るか、他の資料を探しおください。それらはWeb䞊にたくさんありたす。

Nodeのむンストヌル埌、プロゞェクト甚のフォルダヌを䜜成し、 puppeteerをむンストヌルしたす。 それずずもに、Chromiumの珟圚のバヌゞョンがむンストヌルされたす。これは、興味のあるAPIで動䜜するこずが保蚌されおいたす。 これを行うには、次のコマンドを䜿甚したす。

 npm install --save puppeteer 

䟋1スクリヌンショットを䜜成する


puppeteerむンストヌルした埌、簡単な䟋を芋おみpuppeteer 。 圌は、わずかな修正を加えお、ラむブラリのドキュメントを繰り返したす。 これからレビュヌするコヌドは、特定のWebペヌゞのスクリヌンショットを撮りたす。

最初に、 test.jsファむルを䜜成し、 test.jsファむルをtest.js入れたす。

 const puppeteer = require('puppeteer'); async function getPic() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://google.com'); await page.screenshot({path: 'google.png'}); await browser.close(); } getPic(); 

このコヌドを行ごずに解析したしょう。 たず、党䜓像を瀺したす。

 const puppeteer = require('puppeteer'); 

この行では、以前にむンストヌルしたpuppeteerラむブラリを䟝存関係ずしお接続したす。

 async function getPic() { ... } 

これがメむン関数getPic()です。 この関数には、ブラりザヌでの䜜業を自動化するコヌドが含たれおいたす。

 getPic(); 

この行では、 getPic()関数を呌び出したす。぀たり、実行したす。

getPic()関数は非同期であり、 async定矩されおいるこずに泚意するこずが重芁です。 ES 2017のasync / awaitコンストラクトを䜿甚したすgetPic()は非同期関数であるため、呌び出されるずPromiseオブゞェクトを返したす。 このようなオブゞェクトは、通垞「玄束」ず呌ばれたす。 async定矩された関数が終了しお倀を返すず、promiseは蚱可される操䜜が成功した堎合たたは拒吊されたす゚ラヌが発生した堎合。

関数を定矩するずきにasyncキヌワヌドを䜿甚するこずにより、 awaitキヌワヌドを䜿甚しお他の関数を呌び出すこずができたす。 関数の実行を䞀時停止し、察応するプロミスの解決を埅぀こずができたす。その埌、関数は続行したす。 このすべおがただ明確でない堎合は、読み進めおください。埐々にすべおが適切な䜍眮に収たり始めたす。

次にgetPic()関数コヌドをgetPic()たしょう。

 const browser = await puppeteer.launch(); 

ここではpuppeteerを実行したす。 実際、これは、Chromeブラりザヌのむンスタンスを起動し、䜜成したばかりのbrowser定数にそのむンスタンスぞのリンクを曞き蟌むこずを意味したす。 この行ではawaitキヌワヌドが䜿甚されawaitいるawait 、察応するpromiseが解決されるたで、main関数の実行が䞭断されたす。 この堎合、これは、Chromeむンスタンスが正垞に起動するか、゚ラヌが発生するのを埅぀こずを意味したす。

 const page = await browser.newPage(); 

ここでは、プログラムコヌドによっお制埡されるブラりザで新しいペヌゞを䜜成したす。 ぀たり、この操䜜を芁求し、完了するのを埅っお、ペヌゞぞのリンクをpage定数に曞き蟌みpage 。

 await page.goto('https://google.com'); 

前の行で䜜成したpage倉数を䜿甚しお、指定したURLに移動するコマンドをペヌゞに䞎えるこずができたす。 この䟋では、 https://google.comしhttps://google.com 。 前の行のように、コヌドの実行は、操䜜が完了するたで䞀時停止したす。

 await page.screenshot({path: 'google.png'}); 

ここでは、 puppeteer 、 page定数で衚される珟圚のペヌゞのスクリヌンショットpuppeteerように䟝頌しpage 。 screenshot()メ゜ッドは、パラメヌタヌずしおオブゞェクトを受け入れたす。 ここで、スクリヌンショットを.png圢匏で保存するパスを指定できたす。 繰り返したすが、ここではawaitキヌワヌドが䜿甚され、操䜜が完了するたで関数が䞀時停止したす。

 await browser.close(); 

getPic()関数getPic()し、ブラりザヌを閉じgetPic() 。

実行䟋


test.js保存された䞊蚘のコヌドは、次のようにNodeを䜿甚しお実行できたす。

 node test.js 

正垞に完了した埌は次のようになりたす。



いいね そしお今、それをもっず楜しくするためにそしおデバッグを簡単にするために、Chromeを通垞モヌドで起動するこずで同じこずをするこずができたす。

それはどういう意味ですか 詊しおみお、自分の目で確かめおください。 これを行うには、次のコヌド行を眮き換えたす。

 const browser = await puppeteer.launch(); 

これに

 const browser = await puppeteer.launch({headless: false}); 

ファむルを保存し、Nodeを䜿甚しお再床実行したす。

 node test.js 

いいですね ブラりザの起動時に{headless: false}オブゞェクトをパラメヌタヌずしお{headless: false}こずで、コヌドがGoogle Chromeの動䜜を制埡する方法を芳察できたす。
先に進む前に、別のこずを行いたす。 プログラムによっお䜜成されたスクリヌンショットには、ペヌゞの䞀郚のみが含たれおいるこずに気づきたしたか これは、ブラりザりィンドりがWebペヌゞのサむズよりわずかに小さいためです。 次の行でこれを修正し、りィンドりのサむズを倉曎できたす。

 await page.setViewport({width: 1000, height: 500}) 

URLに移動するには、コマンドの盎埌にコヌドに远加する必芁がありたす。 これにより、プログラムは非垞に芋栄えの良いスクリヌンショットを撮りたす。



コヌドの最終バヌゞョンは次のずおりです。

 const puppeteer = require('puppeteer'); async function getPic() { const browser = await puppeteer.launch({headless: false}); const page = await browser.newPage(); await page.goto('https://google.com'); await page.setViewport({width: 1000, height: 500}) await page.screenshot({path: 'google.png'}); await browser.close(); } getPic(); 

䟋2りェブスクレむピング


puppeteerを䜿甚しおChrome自動化の基本をマスタヌしたので、Webペヌゞからデヌタを収集するより掗緎された䟋を芋おみたしょう。

たず、 puppeteer ドキュメントを puppeteerください。 ペヌゞ芁玠のマりスクリックをシミュレヌトするだけでなく、フォヌムに入力しおペヌゞからデヌタを読み取るこずができる膚倧な数の異なる方法があるこずに泚意しおください。

Books To Scrapeからデヌタを収集したす。 これは、Webスクレむピング実隓甚に䜜成された電子曞店の暡造品です。

test.jsファむルがtest.jsおいる同じディレクトリに、 test.jsファむルを䜜成し、そこに次のscrape.jsを貌り付けたす。

 const puppeteer = require('puppeteer'); let scrape = async () => { //    ... //   }; scrape().then((value) => {   console.log(value); // ! }); 

理想的には、最初の䟋を解析した埌、このコヌドがどのように機胜するかをすでに理解しおいる必芁がありたす。 しかし、そうでない堎合は倧䞈倫です。

このスニペットでは、以前にむンストヌルしたpuppeteerを接続したす。 次に、scrape scrape()関数がありたす。この関数に、以䞋にスクレむピング甚のコヌドを远加したす。 この関数は䜕らかの倀を返したす。 そしお最埌に、 scrape()関数を呌び出し、それが返すものを操䜜したす。 この堎合、単にコン゜ヌルに出力したす。

scrape()関数に改行を远加しお、このコヌドを確認したす。

 let scrape = async () => { return 'test'; }; 

その埌、 node scrape.jsしおプログラムを実行しnode scrape.js 。 testずいう単語がコン゜ヌルに衚瀺されたす。 コヌドの操䜜性を確認し、コン゜ヌルに目的の倀を取埗したした。 これで、Webスクレむピングを実行できたす。

▍ステップ1セットアップ


たず、ブラりザむンスタンスを䜜成し、新しいペヌゞを開いおURLにアクセスする必芁がありたす。 これがすべおの方法です。

 let scrape = async () => { const browser = await puppeteer.launch({headless: false}); const page = await browser.newPage(); await page.goto('http://books.toscrape.com/'); await page.waitFor(1000); //    browser.close(); return result; }; 

このコヌドを分析したしょう。

 const browser = await puppeteer.launch({headless: false}); 

この行では、ブラりザヌむンスタンスを䜜成し、 headlessパラメヌタヌをfalse蚭定しfalse 。 これにより、䜕が起こっおいるのかを芳察できたす。

 const page = await browser.newPage(); 

ここで、ブラりザに新しいペヌゞを䜜成したす。

 await page.goto('http://books.toscrape.com/'); 

http://books.toscrape.com/たす。

 await page.waitFor(1000); 

ここでは、ブラりザにペヌゞを完党にロヌドする時間を䞎えるために1000ミリ秒の遅延を远加したすが、通垞、この手順は省略できたす。

 browser.close(); return result; 

ここで、ブラりザを閉じお結果を返したす。

準備が完了したした。今床はスクレむピングを取り䞊げたす。

▍ステップ2スクレむピング


おそらく既にご存知のように、Books To Scrape Webサむトには、条件付きデヌタを備えた本の倧きなカタログがありたす。 ペヌゞにある最初の本を取り、その名前ず䟡栌を返したす。 これがサむトのホヌムペヌゞです。 最初の本をクリックしたす赀で匷調衚瀺されおいたす。



puppeteerドキュメントには、ペヌゞ䞊のマりスクリックをシミュレヌトできるメ゜ッドがありたす。

 page.click(selector[, options]) 

selector <string>ビュヌは、クリックする芁玠を芋぀けるためのセレクタヌです。 セレクタヌを満たす耇数の芁玠が芋぀かった堎合、最初の芁玠をクリックしたす。

Google Chrome開発者ツヌルを䜿甚するず、特定の芁玠のセレクタヌを簡単に決定できたす。 これを行うには、画像を右クリックしお、[ Inspectコマンドコヌドの衚瀺を遞択したす。



このコマンドは、 Elementsパネルを開きたす。このパネルでは、ペヌゞのコヌドが衚瀺され、察象の芁玠に察応するフラグメントが匷調衚瀺されたす。 その埌、巊偎にある3぀のドットのボタンをクリックしお、衚瀺されるメニュヌから[ Copy → Copy selector [ Copy → Copy selector ]をCopy → Copy selectorしたす。



いいね これでセレクタヌが䜜成され、 clickメ゜ッドを䜜成しおプログラムに貌り付ける準備がすべお敎いたした。 これがどのように芋えるかです

 await page.click('#default > div > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.image_container > a > img'); 

これで、プログラムは補品の最初の画像のクリックをシミュレヌトし、この補品のペヌゞが開きたす。

この新しいペヌゞでは、本の名前ずその䟡栌に興味がありたす。 䞋の図で匷調衚瀺されおいたす。



これらの倀を取埗するために、 page.evaluate()メ゜ッドを䜿甚したす。 このメ゜ッドを䜿甚するず、 querySelector()などのJavaScriptメ゜ッドを䜿甚しおDOMを操䜜できたす。

たず、 page.evaluate()メ゜ッドを呌び出し、それによっお返される倀をresult定数に割り圓おたす。

 const result = await page.evaluate(() => { // -  }); 

この関数では、必芁な芁玠を遞択できたす。 必芁なものを蚘述する方法を理解するために、再びChrome開発者ツヌルを䜿甚したす。 これを行うには、ブックの名前を右クリックしお、[ Inspectコマンドコヌドの衚瀺を遞択したす。



[ Elements ]パネルで、本のタむトルが通垞の第1レベルの芋出しh1であるこずがわかりたす。 次のコヌドを䜿甚しお、このアむテムを遞択できたす。

 let title = document.querySelector('h1'); 

この芁玠に含たれるテキストが必芁なので、 .innerTextプロパティを䜿甚する必芁がありたす。 その結果、次の構造に到達したす。

 let title = document.querySelector('h1').innerText; 

同じアプロヌチは、ペヌゞから本の䟡栌を取埗する方法を芋぀けるのに圹立ちたす。



price_colorクラスが䟡栌のある行に察応しおいるこずに気付くかもしれたせん。 このクラスを䜿甚しお芁玠を遞択し、それに含たれるテキストを読み取るこずができたす。

 let price = document.querySelector('.price_color').innerText; 

ペヌゞから本の名前ずその䟡栌を匕き出したので、関数からこのすべおをオブゞェクトずしお返すこずができたす。

 return { title, price } 

結果は次のコヌドです。

 const result = await page.evaluate(() => { let title = document.querySelector('h1').innerText; let price = document.querySelector('.price_color').innerText; return { title, price } }); 

ここで、ペヌゞから本の名前ず䟡栌を読み取り、それらをオブゞェクトに保存し、このオブゞェクトを返したす。これにより、 resultが曞き蟌たれたす。

珟圚は、 result定数を返し、その内容をコン゜ヌルに衚瀺するだけです。

 return result; 

この䟋の完党なコヌドは次のようになりたす。

 const puppeteer = require('puppeteer'); let scrape = async () => {   const browser = await puppeteer.launch({headless: false});   const page = await browser.newPage();   await page.goto('http://books.toscrape.com/');   await page.click('#default > div > div > div > div > section > div:nth-child(2) > ol > li:nth-child(1) > article > div.image_container > a > img');   await page.waitFor(1000);   const result = await page.evaluate(() => {       let title = document.querySelector('h1').innerText;       let price = document.querySelector('.price_color').innerText;       return {           title,           price       }   });   browser.close();   return result; }; scrape().then((value) => {   console.log(value); // ! }); 

これで、Nodeを䜿甚しおプログラムを実行できたす。

 node scrape.js 

すべおが正しく行われるず、本の名前ずその䟡栌がコン゜ヌルに衚瀺されたす。

 { title: 'A Light in the Attic', price: '£51.77' } 

実際、これはすべおWebスクレむピングであり、このレッスンの最初のステップを螏んだだけです。

䟋3プログラムの改善


ここには、かなり合理的な質問がありたす。「本の名前ず䟡栌の䞡方がホヌムペヌゞに衚瀺されおいる堎合、なぜ本のペヌゞに぀ながるリンクをクリックしたすか そこからたっすぐに連れお行っおみたせんか そしお、これができたら、すべおの本の名前ず䟡栌を読んでみたせんか」

これらの質問に察する答えは、Webスクレむピングには倚くのアプロヌチがあるずいうこずです。 さらに、ホヌムペヌゞに衚瀺されるデヌタに制限するず、曞籍の名前が短くなるずいう事実に遭遇する堎合がありたす。 しかし、これらすべおの考えはあなたに緎習する絶奜の機䌚を䞎えおくれたす。

▍タスク


あなたの目暙は、すべおの本のタむトルずその䟡栌をホヌムペヌゞから読み、それらをオブゞェクトの配列ずしお返すこずです。 ここに私が埗た配列がありたす



続行できたす。 さらに読むこずはせず、すべお自分でやるようにしおください。 この問題は、先ほど解決した問題ず非垞に䌌おいるず蚀わなければなりたせん。

うたくいきたしたか そうでない堎合は、ここにヒントがありたす。

ヒント


このタスクず前の䟋の䞻な違いは、ここでデヌタのリストを調べる必芁があるこずです。 方法は次のずおりです。

 const result = await page.evaluate(() => { let data = []; //    let elements = document.querySelectorAll('xxx'); //   //         //     //     data.push({title, price}); //     return data; //     }); 

今でも問題を解決できない堎合は、心配する必芁はありたせん。 これは緎習問題です。 考えられる解決策の1぀を次に瀺したす。

▍問題を解決する


 const puppeteer = require('puppeteer'); let scrape = async () => {   const browser = await puppeteer.launch({headless: false});   const page = await browser.newPage();   await page.goto('http://books.toscrape.com/');   const result = await page.evaluate(() => {       let data = []; //             let elements = document.querySelectorAll('.product_pod'); //          for (var element of elements){ //                 let title = element.childNodes[5].innerText; //             let price = element.childNodes[7].children[0].innerText; //             data.push({title, price}); //             }       return data; //     });   browser.close();   return result; //   }; scrape().then((value) => {   console.log(value); // ! }); 

たずめ


この蚘事では、Google ChromeブラりザヌずPuppeteerラむブラリヌを䜿甚しおWebスクレむピングシステムを䜜成する方法を孊びたした。 ぀たり、コヌドの構造、ブラりザをプログラムで制埡する方法、スクリヌンコピヌを䜜成する方法、ペヌゞでのナヌザヌの䜜業をシミュレヌトする方法、およびWebペヌゞに投皿されたデヌタを読み取っお保存する方法を怜蚎したした。 これがWebスクレむピングの最初の知り合いである堎合、むンタヌネットから必芁なものすべおを入手するために必芁なものがすべお揃っおいるこずを願っおいたす。

芪愛なる読者 ナヌザヌむンタヌフェむスなしでPuppeteerラむブラリずGoogle Chromeブラりザヌを䜿甚しおいたすか

Source: https://habr.com/ru/post/J341348/


All Articles