nodeJS 爬蟲,通過Puppeteer實現滾動載入

NaiveHa發表於2018-09-19

最近在研究爬蟲,所以用自己熟悉的node簡單寫了一個。

開始用的是phantomjs來獲取HTML,但是看了文件之後發現很久沒有維護了,所以就放棄了。

後來尋尋覓覓發現了 Puppeteer,看了下是Google開發的,所以果斷上手試了試,感覺比phantom不知道高到哪裡去了。

B話少說,直接貼專案地址。

github.com/Huoshendame…

專案簡介

技術棧

node、puppeteer、cheerio(雖然puppeteer整合了Jq,但是既然已經裝了就用一下吧)

安裝注意事項

在執行npm install 在安裝 puppeteer的時候會報錯,因為node下載chrome(puppeteer依賴chrome瀏覽器)會報錯。所以先忽略掉chrome

npm install puppeteer --ignore-scripts
複製程式碼

安裝成功之後,在去執行

npm install複製程式碼

裝好之後,手動吧專案裡的 chrome-win 資料夾 放到D盤根目錄。

PS:或者你自己放到自己的指定目錄,但是在專案裡的reptile.js裡面 puppeteer.launch的時候需要指定絕對定位的地址


功能介紹

1.通過Puppeteer開啟頭條新聞頁面 https://www.toutiao.com/ch/news_game/。

2.獲取page例項,通過注入js來實現頁面滾動

3.在通過cheerio,分析dom結構,獲取標題、圖片及連結地址。

4.儲存到本地檔案。(也可以放到DB裡,我這裡是直接介面返回了獲取的資料,並且順手存到了本地檔案)


原始碼

/* 引入相關 工具 */
const fs = require('fs')
const cheerio = require('cheerio')
const puppeteer = require('puppeteer')

/* 定義函式 */
let getListData = async function(Category) {
 /* 初始化 puppeteer*/
 const browser = await puppeteer.launch({
  executablePath: 'D:\\chrome-win\\chrome.exe',//把專案中的這個chrome-win資料夾放到D盤根目錄
  headless: false //這個是 是否開啟chrome視覺化視窗 true是不開啟 false是開啟
 })
 //獲取page例項
 const page = await browser.newPage()
 //我這裡是通過 入參傳過來的 分類來判斷抓取相應頁面的資料
 let url = ''
 switch (Category) {
  case '0':
   url = 'https://www.toutiao.com/ch/news_game/'
   break;
  case '1':
   url = 'https://www.toutiao.com/ch/news_entertainment/'
   break;
  case '2':
   url = 'https://www.toutiao.com/ch/news_history/'
   break;
  case '3':
   url = 'https://www.toutiao.com/ch/news_finance/'
   break;
 }
 //開啟頁面
 await page.goto(url)
 //定義頁面內容及Jquery
 var content , $
 /* 頁面滾動方法 */
 async function scrollPage(i) {
  content = await page.content();
  $ = cheerio.load(content);
  /*執行js程式碼(滾動頁面)*/
  await page.evaluate(function () {
   /* 這裡做的是漸進滾動,如果一次性滾動則不會觸發獲取新資料的監聽 */
   for (var y = 0; y <= 1000*i; y += 100) {
    window.scrollTo(0,y)
   }
  })
  // 獲取資料列表
  const li = $($('.feedBox').find('ul')[0]).find('li')
  return li
 }
 let i = 0
 let li = await scrollPage(++i)
 //如果資料列表 不夠30 則一直獲取
 while (li.length < 30) {
  li = await scrollPage(++i)
 }
 let data = {
   list: []
 }
 /* 封裝返回的資料*/
 li.map(function (index,item) {
  $(item).find('img').attr('src') != undefined ?
   data.list.push({
    src: $(item).find('img').attr('src'),
    title: $($(item).find('.title')).text(),
    source:$($(item).find('.source')).text(),
    href:$($(item).find('.title')).attr('href')
   }):''
 })
 //順手存入本地檔案
 fs.writeFileSync('tt.JSON',JSON.stringify(data))
 fs.writeFileSync('tt.html',content)
 /* 關閉 puppeteer*/
 await browser.close()
  return data
}
module.exports = getListData複製程式碼


相關文章