需要安裝的依賴:
- request
使用request向需要爬取的網站發起一個請求,在回撥裡使用body接收資料
我選取百度相簿,作為本次爬取的網站
使用百度搜素二次元萌妹子,然後在位址列裡將URL複製下來
const request = require('request');
const options = {
method: "GET",
url: "https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=%E4%BA%8C%E6%AC%A1%E5%85%83%E8%90%8C%E5%A6%B9",
headers:{
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}
}
//先列印一下,看看是否抓取到了資料
request(options,(err,res,body)=>{
console.log(err);
console.log(res.statusCode);
console.log(body);
})
複製程式碼
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/9a858d9a735061833659536666b49805ce7b4dd860cf34cb537096667e48faa9.png)
接著,我們需要對資料,進行處理(對返回的資料,進行分析,拿到我們想要的資料,這裡我們想要得到資料是圖片的URL地址)。
處理資料的方式:
- 正規表示式
作為一個程式設計師,處理字串,首先想到的當然是正則了
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/edaf269018e825040badacf29d226d63967e31625b72ee040af7205c587224a4.png)
使用正則去匹配data-url
const request = require('request');
const options = {
method: "GET",
url: "https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=%E4%BA%8C%E6%AC%A1%E5%85%83%E8%90%8C%E5%A6%B9",
headers:{
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}
}
//先列印一下,看看是否抓取到了資料
request(options,(err,res,body)=>{
const reg = /thumbURL":"https?:\/\/.+?&gp=0.jpg/ig;
const urlArr = body.match(reg);
const msgArr = [];
urlArr.forEach(( val,idx ) => {
const reg = /https?:\/\/.+?&gp=0.jpg/;
msgArr.push(val.match(reg)[0]);
})
console.log(msgArr);
})
複製程式碼
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/b316e5ae5f39b43ae7c99df194fb19e6f00004c002637c07de8df7c97609f4e9.png)
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/bd0a9e2b0e2e7503ad344a85bab65fdc2ad3b62c64d71764522a7d28de3856df.png)
接著,我們嘗試著將圖片下載下來
//想要下載圖片,就必須請求圖片的地址
//訪問到圖片的靜態資源後,使用管道流儲存到檔案中
//因為I/O操作是非同步的,所以使用Promise將程式碼改寫一下
const request = require('request');
const fs = require('fs');//寫入檔案,需要匯入fs模組
const options = {
method: "GET",
url: "https://image.baidu.com/search/index?isource=infinity&iname=baidu&tn=baiduimage&word=%E4%BA%8C%E6%AC%A1%E5%85%83%E8%90%8C%E5%A6%B9",
headers:{
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}
}
new Promise(( res,rej ) => {
request(options,( err,response,body ) => {
const reg = /thumbURL":"https?:\/\/.+?&gp=0.jpg/ig;
const urlArr = body.match(reg);
const msgArr = [];
urlArr.forEach(( val,idx ) => {
const reg = /https?:\/\/.+?&gp=0.jpg/;
msgArr.push(val.match(reg)[0]);
})
res(msgArr);
})
}).then( msgArr => {
msgArr.forEach(( val,idx ) => {
request(val).pipe(fs.createWriteStream("./img/"+idx+".jpg"));
})
})
複製程式碼
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/261712e803c2f957dc67d8cc893499282c96e08172bf4df4e72d4819f8403eee.png)
使用正則,可以解析使用JS渲染的頁面,如果發起請求後,body接收的資料返回的是一個頁面結構,則可以使用以下兩個npm包:
- jsdom
- cheerio
jsdom可以將資料解析成DOM結構,cheerio則將資料包裝成jQuery
以百度搜尋為例,如果要抓取搜尋結果的標題內容和連結
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/55b3a987e04be21e383c63d0fbd85bd232aff5fd87d0eb48e7763e0d239b2858.png)
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/f57f891b4e7ffed42a84c1ea5abf111ce616d9b7a84bb4340e44abdacdedbf06.png)
//
const request = require("request")
const {JSDOM} = require("jsdom")
//const cheerio = require("cheerio")
const word = encodeURI("二次元萌妹")
request({
url : "https://www.baidu.com/s?wd="+word,
headers:{
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}
},(err,response,body)=>{
if(err)throw err;
if( response.statusCode >=200 && response.statusCode<300 ){
//JSDOM處理body
let {window} = new JSDOM(body);
let aDOM = window.document.querySelectorAll("h3.t a");
[...aDOM].forEach(ele => {
console.log(ele.text,ele.href);
})
//cheerio處理body
/*let $ = cheerio.load(body);
$("h3.t a").each((i,ele)=>{
console.log($(ele).attr("href"));
console.log($(ele).text());
})*/
}
});
複製程式碼
得到的結果
![使用nodeJS寫一個簡單的小爬蟲](https://i.iter01.com/images/fe92cbd591e8116faf90a71b5b626985bee58690b53324f3ff935fa048f2566f.png)