爬蟲

cheerio

簡介:html

cheerio是node.js的抓取頁面模塊,爲服務器特別定製的,快速、靈活、實施的jQuery核心實現。適合各類web爬蟲程序。node

cheerios官網jquery

爬取鬥圖啦網站圖片例子linux

 
 1 const cheerio = require('cheerio')
 2  const axios = require('axios')
 3  const fs = require('fs')
 4  const path = require('path')
 5  // cheerio 獲取HTML文檔的內容,內容的獲取跟jquery同樣
 6  7  // 起始地址-分析網站結構
 8  let httpUrl = "https://www.doutula.com/article/list/?page=1";
 9 10  // 獲取頁面總數
11  async function getNum() {
12    res = await axios.get(httpUrl)
13    let $ = cheerio.load(res.data)
14    let btnLength = $('.pagination li').length
15    let allNum = $('.pagination li').eq(btnLength - 2).find('a').text()
16    console.log(allNum);
17    return allNum
18  }
19 20  async function spider() {
21    // 獲取全部頁面的總數
22    let allPageNum = await getNum()
23    for(let i=1;i<= 50;i++) {
24      getListPage(i)
25    }
26  }
27 28  async function getListPage(pageNum) {
29    let httpUrl = "https://www.doutula.com/article/list/?page=" + pageNum;
30    let res = await axios.get(httpUrl)
31    // cheerio解析html文檔
32    let $ = cheerio.load(res.data)
33    // 獲取當前頁面的全部的表情頁面的連接
34    $('#home .col-sm-9>a').each((i, element) => {
35      let pageUrl = $(element).attr('href')
36      let title = $(element).find('.random_title').text()
37      let reg = /(.*?)\d/igs;
38      title = reg.exec(title)[1]
39      fs.mkdir(`./img/${title}`, (err) => {
40        if (err) {
41          console.log(err);
42        } else {
43          console.log('成功建立目錄:' + './img/' + title);
44        }
45      })
46      parsePage(pageUrl, title)
47    })
48  }
49 50  async function parsePage(url, title) {
51    let res = await axios.get(url)
52    let $ = cheerio.load(res.data)
53    $('.pic-content img').each((i, element) => {
54      let imgUrl = $(element).attr('src')
55      // 獲取擴展名
56      let extName = path.extname(imgUrl)
57      // 圖片寫入的路徑和名字
58      let imgPath = `./img/${title}/${title}-${i}${extName}`
59      // 建立圖片可寫流
60      let ws = fs.createWriteStream(imgPath)
61      axios.get(imgUrl, { responseType: 'stream' }).then(res => {
62        // 經過管道流入到可寫流的來源流
63        res.data.pipe(ws)
64        console.log('圖片加載完成:', imgPath);
65        // res.data.on('close',() => {
66        //   ws.close()
67        // })
68      })
69    })
70  }
71  spider()

 

 

爬取音樂網站下載音樂:ios

 
 1 // 目標:下載音樂
 2  // 1獲取音樂相關的信息,經過音樂相關的信息獲取mp3地址
 3  // 2如何獲取大量的音樂信息,經過獲取音樂列表
 4  // 3經過音樂的分類頁,獲取音樂列表
 5  6  const axios = require('axios')
 7  const fs = require('fs')
 8  const path = require('path')
 9 10  // 獲取音樂
11  async function getPage(num) {
12    let httpUrl = "http://www.app-echo.com/api/recommend/sound-day?page=" + num
13    let res = await axios.get(httpUrl)
14 15    res.data.list.forEach((item, i) => {
16      let title = item.sound.name
17      let mp3Url = item.sound.source
18      let filename = path.parse(mp3Url).name
19 20      let content = `${title},${mp3Url},${filename}\n`
21      fs.writeFile('music.txt', content, {flag:'a'},() => {
22        console.log('寫入完成:'+ title);
23      })
24      // console.log(title);
25      // console.log(mp3Url);
26      download(mp3Url,filename)
27    })
28  }
29 30  // 下載音樂
31  async function download(mp3Url, filename) {
32    let res = await axios.get(mp3Url, { responseType: "stream" })
33    // 建立可寫流
34    let ws = fs.createWriteStream('./mp3/' + filename + '.mp3')
35    // 經過管道流入到可寫流的來源流
36    res.data.pipe(ws)
37    // res.data.on('close',() => {
38    //   ws.close()
39    // })
40  }
41 42  for(i=1;i<=5; i++) {
43    getPage(i)
44  }

 


 

Puppeteer

出現的背景git

Chrome59(linux、macos)、Chrome60(windows)以後,Chrome自帶headless(無界面)模式很方便作自動化測試或者爬蟲。可是如何和headless模式的Chrome交互則是一個問題。經過啓動Chrome時的命令參行參僅能實現簡易的啓動時初始化操做。Selenium、Webdriver等是一種解決方案,可是每每依賴衆多,不夠扁平。github

Puppteer是谷歌官方出品的一個經過DevTools協議控制headless Chrome的庫。經過Puppeteer的提供api直接控制Chrome模擬大部分用戶操做來進行UI Test或者做爲爬蟲訪問頁面來收集數據。web

做用:ajax

  • 生成頁面的屏幕截圖和PDF。chrome

  • 爬取SPA(單頁應用程序)並生成預渲染的內容(即「 SSR」(服務器端渲染))。

  • 自動化表單提交,UI測試,鍵盤輸入等。

  • 建立最新的自動化測試環境。使用最新的JavaScript和瀏覽器功能,直接在最新版本的Chrome中運行測試。

  • 捕獲站點的時間線跟蹤以幫助診斷性能問題。

  • 測試Chrome擴展程序。

使用和例子

Puppeteer相似其餘框架,經過操做Browser實例來操做瀏覽器作出相應的反應。

 
 1 const puppeteer = require('puppeteer')
 2  3  (async () => {
 4      const browser = await puppeteer.launch();
 5      const page = await browser.newPage();
 6      await page.to('http://rennaiqian.com');
 7      await page.screenshot({path:'example.png'});
 8      await page.pdf({path:'example.pdf',format:'A4'});
 9      await browser.close()
10  })()

 

上述代碼經過puppeteer的launch方法生成了一個browser的實例,對應於瀏覽器,launch方法能夠傳入配置選項,比較有用的是在本地調試時傳入{headless:false}能夠關閉headless模式。

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

 

browser.newPage方法能夠打開一個新選項卡並返回選項卡的實例page,經過page上的各類方法能夠對頁面進行經常使用操做。上述代碼就進行了截屏和打印pdf的操做。

 

爬蟲總結

1.爬蟲介紹

經過模擬瀏覽器的請求,服務器根據咱們的請求返回咱們想要的數據,將數據解析出來,而且進行保存

2.爬蟲流程

1-目標:肯定你想要獲取的數據

  1. 肯定想要的數據在什麼頁面

  2. 肯定在哪些頁面能夠連接到這些頁面

  3. 尋找頁面之間和數據之間的規律

     

    2-分析頁面

  4. 獲取數據的方法(正則,cherrio)

  5. 分析數據是經過ajax請求的數據,仍是html裏自帶的數據

  6. 若是是經過AjAX請求的數據,那麼須要獲取ajax請求的連接,通常請求到的數據都爲JSON格式數據,那麼就容易解析

  7. 若是數據在HTML裏面,那麼就用cherrio經過選擇器將內容選中

     

    3-編寫單個數據獲取的案例

  8. 解析出分類頁的連接地址

  9. 解析出列表頁的連接地址

  10. 解析出詳情頁的連接地址

  11. 解析詳情頁裏面想要獲取的數據

  12. 將數據進行保存到本地或者是數據庫

     

    4-若是遇到阻礙進行反爬蟲對抗

  13. User-Agent是不是正常瀏覽器的信息

  14. 將請求頭設置成跟瀏覽器同樣的內容

  15. 由於爬蟲的爬取速度過快,會致使封ip。1那麼能夠下降速度進行解決,2能夠使用代理進行解決

  16. 若是設置須要憑證,那麼能夠採用無界面瀏覽器真實模擬。

 

3.請求數據的庫

request,axiso:經過庫,幫助咱們快速實現HTTP請求包的打包

1  request.get('請求地址', {
2     '請求頭字段':'請求頭的value值'         
3  },(res) => { 處理返回的內容 })

 

axios優點會更明顯,先後端通殺,先後端調用方式一致

 axios.get('請求地址', 參數對象).then((res) => {
     console.log(res)
 })

 

axios獲取圖片

 
1 axios({
2      method: 'get',
3      url: 'http://bit.ly/2mTM3ny',
4      responseType: 'stream'
5  })
6  .then((res) => {
7      res.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
8  })

 

puppeteer:徹底模擬瀏覽器

打開瀏覽器

 1  let options = {
 2      headless: true, // 是不是無界面瀏覽器
 3      slowMo: 250, // 調試時能夠減慢操做速度
 4      defaultViewport: { //設置視寬的寬高
 5          width: 1200
 6          height: 800
 7      },
 8      timeout: 3000, // 默認超時時間3秒
 9  }
10  let browser = await puppeteer.launch(options)

 

打開新標籤頁

1  let page = await borwser.newPage()

 

獲取全部瀏覽器中的頁面

 
1 let page = await browser.pages()

 

關閉瀏覽器

1  borwser.close()

 

將頁面跳轉至

1  await page.goto(url)

 

獲取頁面的對象並進行操做

1  let btn = await page.$(selector)
2  let input = await page.$(selector)
3  // 點擊按鈕
4  btn.click()
5  // 聚焦到輸入框
6  input.forcus()

 

在頁面上寫入內容或者鍵盤按鍵

 
1 await page.keyboard.type('hello World!');
2  await page.keyboard.press('ArrowLeft');
3  await page.keyboard.down('Shift');

 

截獲頁面請求

 1  await page.setRequestInterception(true)
 2  page.on('request', request => {
 3      // request 包含請求的全部信息
 4      if(你想要的條件) {
 5          request.continue()
 6      } else {
 7          request.respond({
 8              status: 404,
 9              contentType: 'text/plain',
10              body: 'Not Found!'
11          })
12      }
13  })

 

獲取瀏覽器的信息和內容

1  page.$eval(selector, (item) => { return item })
2  page.$$eval(selector, (item) => { return item })

 

 

Demo

GitHub上有:MongoDB數據庫+Node爬蟲-案例demo,歡迎Clone學習

更多爬蟲相關小案例,歡迎進入github選擇"爬蟲-Reptiles爬蟲"文件夾查看clone

相關文章
相關標籤/搜索