網絡爬蟲:(英語:web crawler),也叫網絡蜘蛛(spider),是一種用來自動瀏覽萬維網的網絡機器人。其目的通常爲編纂網絡索引。通常應用在網絡搜索引擎上,搜索引擎經過爬蟲軟件更新自身的網站內容供用戶搜索。php
爬蟲訪問網站的過程會消耗目標系統資源。很多網絡系統並不默許爬蟲工做。所以在訪問大量頁面時,爬蟲須要考慮到規劃、負載,還須要講「禮貌」。 不肯意被爬蟲訪問、被爬蟲主人知曉的公開站點可使用robots.txt文件之類的方法避免訪問。這個文件能夠要求機器人只對網站的一部分進行索引,或徹底不做處理。css
咱們最終的目標是實現爬取前程無憂web前端工程師的職位名稱,公司名稱,工做地點,薪資,發佈時間.html
固然,咱們能夠進行深度爬取,深度爬取涉及到對網頁的二次請求.雖然node爬蟲相對於python爬蟲有自身的優勢,能夠憑藉強大的異步特性很輕鬆的實現高效的異步併發請求,節省cpu
的開銷。 可是這會有較大機率被網站檢測到你在極短的時間內對網頁進行量化請求,會被認定是DDos
攻擊或者危害本網站,會觸發反爬機制.因此這裏咱們不討論深刻爬取,有興趣的能夠了解一下python的深度爬取.前端
咱們要爬取頁面的數據,第一步是要先分析清楚頁面結構,要爬哪些頁面,頁面的結構是怎樣的,需不須要登陸;有沒有ajax
接口,返回什麼樣的數據等。node
分析清楚要爬取哪些頁面和ajax
,就要去抓取數據了。現在的網頁的數據,大致分爲同步頁面和ajax
接口。同步頁面數據的抓取就須要咱們先分析網頁的結構,python抓取數據通常是經過正則表達式匹配來獲取須要的數據;node有一個cheerio的工具,能夠將獲取的頁面內容轉換成jquery
對象,而後就能夠用jquery
強大的dom API
來獲取節點相關數據, 其實你們看源碼,這些API
本質也就是正則匹配。ajax
接口數據通常都是json
格式的,處理起來仍是比較簡單的。python
抓取的數據後,會作簡單的篩選,而後將須要的數據先保存起來,以便後續的分析處理。固然咱們能夠用MySQL
和Mongodb
等數據庫存儲數據。這裏,咱們爲了方便,直接採用文件存儲。jquery
前端展現頁面,將數據展現出來才更直觀,方便咱們分析統計。 固然了,對於數據可視化的操做有不少,最最多見的就是咱們以前學的echarts
圖表可視化,你們能夠多看看這個插件的使用.git
Superagent
是個輕量的的http
方面的庫,是nodejs
裏一個很是方便的客戶端請求代理模塊,當咱們須要進行get、post、head等網絡請求時, 會用到它。github
Superagent-charset
是一個對字符集處理的一個輕量級的庫, 能讓字符集之間實現互相轉化。web
Cheerio你們能夠理解成一個 Node.js
版的 jquery
,用來從網頁中以css
selector 取數據,使用方式跟 jquery
如出一轍。
node-xlsx
庫是目前 Github
上 star 數量最多的處理 Excel 的庫,功能強大,可以對excel文檔進行讀取,寫入等操做。
咱們先進入想要爬取的前程無憂web前端工程師搜索頁面
https://search.51job.com/list/020000,000000,0000,00,9,99,web%25E5%2589%258D%25E7%25AB%25AF,2,1.htmllang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare=
複製代碼
而後咱們對這一行進行分析,按F12進入檢查,這四個標籤分別對應什麼標籤
const charset = require('superagent-charset')
const cheerio = require('cheerio')
const request = charset(require('superagent'))
const fs = require('fs')
const xlsx = require('node-xlsx')
複製代碼
request
.get(url, {
encoding: null,
headers: {
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) Gecko/20100101 Firefox/57.0'
}
})
.charset('gbk')
.end((err, res) => {
if (err) {
console.log('爬取失敗!')
} else {
// console.log(res);
// 調用 cheerio.load() 方法,生成一個相似於 jQuery 的對象
let $ = cheerio.load(res.text)
// 獲取對象中el的元素
let list = $('#resultList .el').not('.title')
list.each((index, element) => {
let line = []
const el = $(element)
// 設置每條數據的id
// line.push(data.length+1)
// 獲取數據中的職位
line.push(el.find('.t1 span a').attr('title'))
// 獲取數據中的公司
line.push(el.find('.t2 a').text())
// 獲取數據中的地址
line.push(el.find('.t3').text())
// 獲取數據中的薪資
line.push(el.find('.t4').text())
// 獲取數據中的發佈時間
line.push(el.find('.t5').text())
data.push(line)
})
} else {
return false
}
}
// console.log(data)
writeXls(data)
})
}
複製代碼
// 嘗試進行多頁面爬取
page++
if (page <= endPage) {
// 根據地址欄地址找出規律
let url =
'https://search.51job.com/list/020000,000000,0000,00,9,99,web%25E5%2589%258D%25E7%25AB%25AF,2,' +page +'.html?lang=c&stype=1&postchannel=0000&workyear=99&cotype=99°reefrom=99&jobterm=99&companysize=99&lonlat=0%2C0&radius=-1&ord_field=0&confirmdate=9&fromType=&dibiaoid=0&address=&line=&specialarea=00&from=&welfare='
start(url) //進行遞歸抓取
複製代碼
function writeXls(data) {
var buffer = xlsx.build([
{
name: 'sheet1',
data: data
}
])
fs.writeFileSync('data.xlsx', buffer, { flag: 'w' })
}
複製代碼