簡介:html
cheerio是node.js的抓取頁面模塊,爲服務器特別定製的,快速、靈活、實施的jQuery核心實現。適合各類web爬蟲程序。node
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 }
出現的背景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的操做。
經過模擬瀏覽器的請求,服務器根據咱們的請求返回咱們想要的數據,將數據解析出來,而且進行保存
肯定想要的數據在什麼頁面
肯定在哪些頁面能夠連接到這些頁面
尋找頁面之間和數據之間的規律
獲取數據的方法(正則,cherrio)
分析數據是經過ajax請求的數據,仍是html裏自帶的數據
若是是經過AjAX請求的數據,那麼須要獲取ajax請求的連接,通常請求到的數據都爲JSON格式數據,那麼就容易解析
若是數據在HTML裏面,那麼就用cherrio經過選擇器將內容選中
解析出分類頁的連接地址
解析出列表頁的連接地址
解析出詳情頁的連接地址
解析詳情頁裏面想要獲取的數據
將數據進行保存到本地或者是數據庫
User-Agent是不是正常瀏覽器的信息
將請求頭設置成跟瀏覽器同樣的內容
由於爬蟲的爬取速度過快,會致使封ip。1那麼能夠下降速度進行解決,2能夠使用代理進行解決
若是設置須要憑證,那麼能夠採用無界面瀏覽器真實模擬。
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 })
GitHub上有:
更多爬蟲相關小案例,歡迎進入