特別申明:閱讀本文以後,請勿濫用爬蟲採集資源,攻擊他人服務器。javascript
網絡爬蟲(又稱爲網頁蜘蛛,網絡機器人,在FOAF社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。另一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。html
開門見山,小編所接觸到的爬蟲分爲兩種,一種爲基本的http或https請求,使用網絡請求來獲取目標內容。第二種爲無頭瀏覽器,能夠將目標頁面直接運行在無頭瀏覽器中。兩種方法各有利弊,接下來咱們詳細瞭解一下。前端
小編是一名前端程序員,熟悉javascript,因此這裏的舉例都是使用nodejs代碼。先來講說第一種爬蟲,使用http請求的方式。java
咱們可使用nodejs種的http(s)模塊來請求目標網址,也可使用axios
這樣的第三方庫來請求網頁。拿到html後使用html解析庫將其解析爲方便操做的js對象,而後抓去目標內容。解析庫這裏推薦使用cheerio
。cheerio提供了相似jQuery的操做方法,能夠輕鬆的抓去到咱們想要的內容。node
// demo1
const cheerio = require('cheerio')
const axios = require('axios')
async function main() {
const resp = await axios.get('https://www.jianshu.com/')
console.log(resp.data)
}
main()
複製代碼
經過node demo1
執行demo1,咱們能夠拿到簡書首頁的html。 ios
咱們如今來完善demo1的代碼,將html使用cheerio解析。程序員
// demo1
const cheerio = require('cheerio')
const axios = require('axios')
async function main() {
const resp = await axios.get('https://www.jianshu.com/')
const $ = cheerio.load(resp.data)
const articleList = []
$('#list-container li').each((i, el) => {
articleList.push({
id: $(el).attr('id').replace('note-', ''),
title: unescape($(el).find('.title').html().replace(/&#x/g, '%u').replace(/;/g, '')),
href: $(el).find('.title').attr('href'),
})
})
console.log(articleList)
}
main()
複製代碼
這樣咱們就拿到了文章的id,標題和連接了。axios
這種方式抓取數據的優勢是效率高,佔用的硬件資源也不多。可是這種方法也存在一些劣勢。例如懶加載頁面就很難爬取。由於懶加載的頁面的內容是由瀏覽器js動態加載的,這樣一來,咱們所請求到的頁面,因爲js尚未將內容渲染到頁面上,咱們就沒法正確拿到頁面內容,而且咱們的請求也沒法提供頁面js所需的運行環境。這時候就要引出咱們的另外一種爬蟲了。瀏覽器
無頭瀏覽器是指沒有操做界面的,在後臺運行的網絡瀏覽器程序。經常使用的無頭瀏覽器有PhantomJS,Selenium,Puppeteer等(還有不少不少哦,有興趣能夠本身查閱)。bash
無頭瀏覽器常被用於自動化測試、爬蟲等技術。它提供了瀏覽器js所需的運行環境,咱們能夠利用這一點,來對付懶加載的頁面。
Puppeteer是谷歌發佈的一款Chromium無頭瀏覽器。在這裏咱們以Puppeteer爲例,來寫一些小demo。
// demo2
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch({
// 是否爲無頭,無頭模式下沒有用戶操做界面
headless: false,
defaultViewport: null
})
const page = await browser.newPage();
await page.goto('https://www.jianshu.com/u/04d11dd2f924');
}
main()
複製代碼
咱們來使用node demo2
來執行:
咱們如今已經使用代碼打開了一個瀏覽器窗口。接下來,咱們將繼續完善demo2來抓取此頁面的內容。
// demo2
const puppeteer = require('puppeteer');
async function main() {
const browser = await puppeteer.launch({
// 是否爲無頭,無頭模式下沒有用戶操做界面
headless: false,
defaultViewport: null,
devtools: true,
})
const page = await browser.newPage();
await page.goto('https://www.jianshu.com/u/04d11dd2f924');
const articleList = await page.$$eval('#list-container li', els =>
els.map(el => {
const id = el.dataset.noteId
const title = el.querySelector('.title').innerText
const url = el.querySelector('.title').href
return {id, title, url}
})
)
console.log(articleList)
}
main()
複製代碼
執行該代碼,咱們獲得以下結果:
這就是無頭瀏覽器的基本使用。它還提供了不少方便操做的API,例如page.waitFor(selector, pageFun)
方法,能夠等待某個元素出如今頁面後再去執行pageFun方法.還有page.addScriptTag(options)
方法,能夠直接在頁面注入你本身的js腳本。
在這裏,再次申明,請勿濫用爬蟲採集資源,攻擊他人服務器。
http 方式: 優勢:佔用的硬件資源少,響應速度更快; 缺點:沒法抓取懶加載頁面,沒法獲取更多信息,例如cookie,localStorage等。
無頭瀏覽器 方式: 優勢:提供完整瀏覽器運行環境,能夠抓取懶加載頁面的內容,也能夠獲取頁面cookie等本地存儲,能夠在頁面注入js代碼,能夠模擬鍵盤輸入,鼠標點擊等操做; 缺點:佔用的硬件資源高,會去執行頁面代碼,在關閉無頭模式的狀況下還要去渲染頁面,響應速度慢。
詳細對比了兩種方式之後,咱們發現兩種方式各有利弊。其實,在實際使用中,咱們能夠混搭使用,既保證了執行效率,一樣也能保證信息的完整性。
今天就介紹道這裏了,喜歡的簡友能夠點贊並關注,隨後我就繼續更新幾篇爬蟲相關的文章。
本文版權全部,禁止轉載!