久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      視頻教程推薦:nodejs 教程

      我們將學(xué)到什么?

      在本教程中,您將學(xué)習(xí)如何使用 JavaScript 自動(dòng)化和清理 web 。要做到這一點(diǎn),我們將使用 Puppeteer 。Puppeteer是一個(gè)允許我們控制無(wú)頭Chrome 的 Node 庫(kù) API。Headless Chrome是一種在不真實(shí)運(yùn)行 Chrome 的情況下運(yùn)行 Chrome 瀏覽器的方法。

      如果這一切都沒(méi)有意義,您真正需要知道的是,我們將編寫(xiě) JavaScript 代碼,使 Google Chrome 實(shí)現(xiàn)自動(dòng)化。

      開(kāi)始之前

      開(kāi)始之前,您需要在計(jì)算機(jī)上安裝 Node 8+。您可以在此處進(jìn)行安裝。確保選擇「當(dāng)前」版本 8+ 版本。

      如果您以前從未使用過(guò) Node 并想學(xué)習(xí),請(qǐng)查看:學(xué)習(xí) Node JS 3 種最佳在線 Node JS 課程。

      安裝完 Node 后,創(chuàng)建一個(gè)新的項(xiàng)目文件夾并安裝 Puppeteer。 Puppeteer 附帶了 Chromium 的最新版本,該版本可以與 API 一起使用:

      npm install --save puppeteer

      例 #1 — 截圖

      安裝完 Puppeteer 之后,我們將首先介紹一個(gè)簡(jiǎn)單的示例。此示例來(lái)自Puppeteer 文檔(進(jìn)行了少量更改)。我們將通過(guò)代碼逐步介紹對(duì)您訪問(wèn)的網(wǎng)站如何截圖。

      首先,創(chuàng)建一個(gè)名為test.js的文件,然后復(fù)制以下代碼:

      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();

      讓我們逐行瀏覽這個(gè)例子。

      • 第1行: 我們需要我們先前安裝的 Puppeteer 依賴(lài)項(xiàng)
      • 第3-10行:這是我們的主函數(shù)getPic()。該函數(shù)將保存我們所有的自動(dòng)化代碼。
      • 第12行:在第12行上,我們調(diào)用getPic()函數(shù)。

      需要注意的是,getPic()函數(shù)是一個(gè)異步函數(shù),并利用了新的ES 2017async/await功能。由于這個(gè)函數(shù)是異步的,所以當(dāng)調(diào)用時(shí)它返回一個(gè)Promise。當(dāng)Async函數(shù)最終返回值時(shí),Promise將被解析(如果存在錯(cuò)誤,則Reject)。

      由于我們使用的是async函數(shù),因此我們可以使用await表達(dá)式,該表達(dá)式將暫停函數(shù)執(zhí)行并等待Promise解析后再繼續(xù)。 如果現(xiàn)在所有這些都沒(méi)有意義,那也沒(méi)關(guān)系。隨著我們繼續(xù)學(xué)習(xí)教程,它將變得更加清晰。

      現(xiàn)在,我們概述了主函數(shù),讓我們深入了解其內(nèi)部功能:

      • 第4行:
      const browser = await puppeteer.launch();

      這是我們實(shí)際啟動(dòng) puppeteer 的地方。實(shí)際上,我們正在啟動(dòng) Chrome 實(shí)例,并將其設(shè)置為等于我們新創(chuàng)建的browser變量。由于我們使用了await關(guān)鍵字,因此該函數(shù)將在此處暫停,直到Promise解析(直到我們成功創(chuàng)建 Chrome 實(shí)例或出錯(cuò))為止。

      • 第5行:
      const page = await browser.newPage();

      在這里,我們?cè)谧詣?dòng)瀏覽器中創(chuàng)建一個(gè)新頁(yè)面。我們等待新頁(yè)面打開(kāi)并將其保存到我們的page變量中。

      • 第6行:
      await page.goto('https://google.com');

      使用我們?cè)诖a的最后一行中創(chuàng)建的page,現(xiàn)在可以告訴page導(dǎo)航到URL。在此示例中,導(dǎo)航到 google。我們的代碼將暫停,直到頁(yè)面加載完畢。

      • 第7行:
      await page.screenshot({path: 'google.png'});

      現(xiàn)在,我們告訴 Puppeteer 截取當(dāng)前頁(yè)面的屏幕。screenshot()方法將自定義的.png屏幕截圖的保存位置的對(duì)象作為參數(shù)。同樣,我們使用了await關(guān)鍵字,因此在執(zhí)行操作時(shí)我們的代碼會(huì)暫停。

      • 第9行:
      await browser.close();

      最后,我們到了getPic()函數(shù)的結(jié)尾,并且關(guān)閉了browser。

      運(yùn)行示例

      您可以使用 Node 運(yùn)行上面的示例代碼:

      node test.js

      這是生成的屏幕截圖:

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取
      太棒了!為了增加樂(lè)趣(并簡(jiǎn)化調(diào)試),我們可以不以無(wú)頭方式運(yùn)行代碼。

      這到底是什么意思?自己嘗試一下,看看吧。更改代碼的第4行從:

      const browser = await puppeteer.launch();

      改為:

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

      然后使用 Node 再次運(yùn)行:

      node test.js

      太酷了吧?當(dāng)我們使用{headless:false}運(yùn)行時(shí),您可以真實(shí)看到 Google Chrome 按照您的代碼工作。

      在繼續(xù)之前,我們將對(duì)這段代碼做最后一件事。還記得我們的屏幕截圖有點(diǎn)偏離中心嗎?那是因?yàn)槲覀兊捻?yè)面有點(diǎn)小。我們可以通過(guò)添加以下代碼行來(lái)更改頁(yè)面的大?。?/p>

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

      這個(gè)屏幕截圖更好看點(diǎn):

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      這是本示例的最終代碼:

      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-讓我們抓取一些數(shù)據(jù)

      既然您已經(jīng)了解了 Headless Chrome 和 Puppeteer 的工作原理,那么讓我們看一個(gè)更復(fù)雜的示例,在該示例中我們事實(shí)上可以抓取一些數(shù)據(jù)。

      首先, 在此處查看 Puppeteer 的 API 文檔。 如您所見(jiàn),我們有很多方法可以使用, 不僅可以點(diǎn)擊網(wǎng)站,還可以填寫(xiě)表格,輸入內(nèi)容和讀取數(shù)據(jù)。

      在本教程中,我們將抓取 Books To Scrape ,這是一家專(zhuān)門(mén)設(shè)置的假書(shū)店,旨在幫助人們練習(xí)抓取。

      在同一目錄中,創(chuàng)建一個(gè)名為scrape.js的文件,并插入以下樣板代碼:

      const puppeteer = require('puppeteer');  let scrape = async () => {   // 實(shí)際的抓取從這里開(kāi)始...    // 返回值 };  scrape().then((value) => {     console.log(value); // 成功! });

      理想情況下,在看完第一個(gè)示例之后,上面的代碼對(duì)您有意義。如果沒(méi)有,那沒(méi)關(guān)系!

      我們上面所做的需要以前安裝的puppeteer依賴(lài)關(guān)系。然后我們有scraping()函數(shù),我們將在其中填入抓取代碼。此函數(shù)將返回值。最后,我們調(diào)用scraping函數(shù)并處理返回值(將其記錄到控制臺(tái))。

      我們可以通過(guò)在scrape函數(shù)中添加一行代碼來(lái)測(cè)試以上代碼。試試看:

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

      現(xiàn)在,在控制臺(tái)中運(yùn)行node scrape.js。您應(yīng)該返回test!完美,我們返回的值正在記錄到控制臺(tái)?,F(xiàn)在我們可以開(kāi)始補(bǔ)充我們的scrape函數(shù)。

      步驟1:設(shè)置

      我們需要做的第一件事是創(chuàng)建瀏覽器實(shí)例,打開(kāi)一個(gè)新頁(yè)面,然后導(dǎo)航到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); // Scrape browser.close();   return result;};

      太棒了!讓我們逐行學(xué)習(xí)它:

      首先,我們創(chuàng)建瀏覽器,并將headless模式設(shè)置為false。這使我們可以準(zhǔn)確地觀察發(fā)生了什么:

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

      然后,我們?cè)跒g覽器中創(chuàng)建一個(gè)新頁(yè)面:

      const page = await browser.newPage();

      接下來(lái),我們轉(zhuǎn)到books.toscrape.com URL:

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

      我選擇性地添加了1000毫秒的延遲。盡管通常沒(méi)有必要,但這將確保頁(yè)面上的所有內(nèi)容都加載:

      await page.waitFor(1000);

      最后,完成所有操作后,我們將關(guān)閉瀏覽器并返回結(jié)果。

      browser.close(); return result;

      步驟2:抓取

      正如您現(xiàn)在可能已經(jīng)確定的那樣,Books to Scrape 擁有大量的真實(shí)書(shū)籍和這些書(shū)籍的偽造數(shù)據(jù)。我們要做的是選擇頁(yè)面上的第一本書(shū),然后返回該書(shū)的標(biāo)題和價(jià)格。這是要抓取的圖書(shū)的主頁(yè)。我有興趣點(diǎn)第一本書(shū)(下面紅色標(biāo)記)
      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      查看 Puppeteer API,我們可以找到單擊頁(yè)面的方法:

      page.click(selector[, options])
      • selector 用于選擇要單擊的元素的選擇器,如果有多個(gè)滿足選擇器的元素,則將單擊第一個(gè)。

      幸運(yùn)的是,使用 Google Chrome 開(kāi)發(fā)者工具可以非常輕松地確定特定元素的選擇器。只需右鍵單擊圖像并選擇檢查:
      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      這將打開(kāi)元素面板,突出顯示該元素?,F(xiàn)在,您可以單擊左側(cè)的三個(gè)點(diǎn),選擇復(fù)制,然后選擇復(fù)制選擇器:

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      太棒了!現(xiàn)在,我們復(fù)制了選擇器,并且可以將click方法插入程序。像這樣:

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

      我們的窗口將單擊第一個(gè)產(chǎn)品圖像并導(dǎo)航到該產(chǎn)品頁(yè)面!

      在新頁(yè)面上,我們對(duì)商品名稱(chēng)和商品價(jià)格均感興趣(以下以紅色概述)

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取
      為了檢索這些值,我們將使用page.evaluate()方法。此方法使我們可以使用內(nèi)置的 DOM 選擇器,例如querySelector()。

      我們要做的第一件事是創(chuàng)建page.evaluate()函數(shù),并將返回值保存到變量result中:

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

      在函數(shù)里,我們可以選擇所需的元素。我們將使用 Google Developers 工具再次解決這一問(wèn)題。右鍵單擊標(biāo)題,然后選擇檢查:

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      正如您將在 elements 面板中看到的那樣,標(biāo)題只是一個(gè)h1元素。我們可以使用以下代碼選擇此元素:

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

      由于我們希望文本包含在此元素中,因此我們需要添加.innerText-最終代碼如下所示:

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

      同樣,我們可以通過(guò)單擊右鍵檢查元素來(lái)選擇價(jià)格:

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取

      如您所見(jiàn),我們的價(jià)格有price_color類(lèi),我們可以使用此類(lèi)選擇元素及其內(nèi)部文本。這是代碼:

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

      現(xiàn)在我們有了所需的文本,可以將其返回到一個(gè)對(duì)象中:

      return {   title,   price }

      太棒了!我們選擇標(biāo)題和價(jià)格,將其保存到一個(gè)對(duì)象中,然后將該對(duì)象的值返回給result變量。放在一起是這樣的:

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

      剩下要做的唯一一件事就是返回result,以便可以將其記錄到控制臺(tái):

      return result;

      您的最終代碼應(yīng)如下所示:

      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 > p > p > p > p > section > p:nth-child(2) > ol > li:nth-child(1) > article > p.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); // 成功! });

      您可以通過(guò)在控制臺(tái)中鍵入以下內(nèi)容來(lái)運(yùn)行 Node 文件:

      node scrape.js // { 書(shū)名: 'A Light in the Attic', 價(jià)格: '£51.77' }

      您應(yīng)該看到所選圖書(shū)的標(biāo)題和價(jià)格返回到屏幕上!您剛剛抓取了網(wǎng)頁(yè)!

      示例 #3 ——完善它

      現(xiàn)在您可能會(huì)問(wèn)自己,當(dāng)標(biāo)題和價(jià)格都顯示在主頁(yè)上時(shí),為什么我們要點(diǎn)擊書(shū)?為什么不從那里抓取呢?而在我們嘗試時(shí),為什么不抓緊所有書(shū)籍的標(biāo)題和價(jià)格呢?

      因?yàn)橛泻芏喾椒梢宰ト【W(wǎng)站! (此外,如果我們留在首頁(yè)上,我們的標(biāo)題將被刪掉)。但是,這為您提供了練習(xí)新的抓取技能的絕好機(jī)會(huì)!

      挑戰(zhàn)
      目標(biāo) ——從首頁(yè)抓取所有書(shū)名和價(jià)格,并以數(shù)組形式返回。這是我最終的輸出結(jié)果:

      使用Node.js+Chrome+Puppeteer實(shí)現(xiàn)網(wǎng)站的爬取
      開(kāi)始!看看您是否可以自己完成此任務(wù)。與我們剛創(chuàng)建的上述程序非常相似,如果卡住,請(qǐng)向下滾動(dòng)…
      GO! See if you can accomplish this on your own. It’s very similar to the above program we just created. Scroll down if you get stuck…


      提示:
      此挑戰(zhàn)與上一個(gè)示例之間的主要區(qū)別是需要遍歷大量結(jié)果。您可以按照以下方法設(shè)置代碼來(lái)做到這一點(diǎn):

      const result = await page.evaluate(() => {   let data = []; // 創(chuàng)建一個(gè)空數(shù)組   let elements = document.querySelectorAll('xxx'); // 選擇全部        // 遍歷每一個(gè)產(chǎn)品     // 選擇標(biāo)題     // 選擇價(jià)格     data.push({title, price}); // 將數(shù)據(jù)放到數(shù)組里, 返回?cái)?shù)據(jù);      // 返回?cái)?shù)據(jù)數(shù)組 });

      如果您不明白,沒(méi)事!這是一個(gè)棘手的問(wèn)題…… 這是一種可能的解決方案。在以后的文章中,我將深入研究此代碼及其工作方式,我們還將介紹更高級(jí)的抓取技術(shù)。如果您想收到通知,請(qǐng)務(wù)必 在此處輸入您的電子郵件 。

      方案:

      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 = []; // 創(chuàng)建一個(gè)空數(shù)組, 用來(lái)存儲(chǔ)數(shù)據(jù)         let elements = document.querySelectorAll('.product_pod'); // 選擇所有產(chǎn)品          for (var element of elements){ // 遍歷每個(gè)產(chǎn)品             let title = element.childNodes[5].innerText; // 選擇標(biāo)題             let price = element.childNodes[7].children[0].innerText; // 選擇價(jià)格              data.push({title, price}); // 將對(duì)象放進(jìn)數(shù)組 data          }          return data; // 返回?cái)?shù)組 data     });      browser.close();     return result; //  返回?cái)?shù)據(jù) };  scrape().then((value) => {     console.log(value); // 成功! });

      結(jié)束語(yǔ):

      感謝您的閱讀!

      英文原文地址:https://codeburst.io/a-guide-to-automating-scraping-the-web-with-javascript-chrome-puppeteer-node-js-b18efb9e9921

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)