nodeJS 爬蟲,經過Puppeteer實現滾動加載

最近在研究爬蟲,因此用本身熟悉的node簡單寫了一個。html

開始用的是phantomjs來獲取HTML,可是看了文檔以後發現好久沒有維護了,因此就放棄了。node

後來尋尋覓覓發現了 Puppeteer,看了下是Google開發的,因此果斷上手試了試,感受比phantom不知道高到哪裏去了。git

B話少說,直接貼項目地址。github

github.com/Huoshendame…
chrome

項目簡介

技術棧

node、puppeteer、cheerio(雖然puppeteer集成了Jq,可是既然已經裝了就用一下吧)npm

安裝注意事項

在運行npm install 在安裝 puppeteer的時候會報錯,由於node下載chrome(puppeteer依賴chrome瀏覽器)會報錯。因此先忽略掉chrome瀏覽器

npm install puppeteer --ignore-scripts
複製代碼

安裝成功以後,在去運行bash

npm install複製代碼

裝好以後,手動吧項目裏的 chrome-win 文件夾 放到D盤根目錄。less

PS:或者你本身放到本身的指定目錄,可是在項目裏的reptile.js裏面 puppeteer.launch的時候須要指定絕對定位的地址dom


功能介紹

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複製代碼
相關文章
相關標籤/搜索