現在Node
這麼火,爲什麼不用他寫個爬蟲呢。
那麼,開始吧!
技術:
puppeteer
:- 由Google團隊開發,該工具可以理解成我們日常使用的Chrome的無界面版本以及對其進行操控的js接口套裝。
- 常見用法:單元測試,性能測試,爬蟲。
- 項目地址:https://github.com/GoogleChrome/puppeteer
Egg.js
:- 由阿里團隊開發,其宗旨是:爲企業級框架和應用而生,希望由 Egg.js 孕育出更多上層框架,幫助開發團隊和開發人員降低開發和維護成本。
- 項目地址:https://github.com/eggjs/egg/
安裝:
環境 :puppeteer本身依賴6.4以上的Node,爲了配合使用async/await,推薦使用7.6版本以上的Node。
1. 初始化項目:
使用egg.js
初始話項目:
$ npm i egg-init -g
$ egg-init egg-example --type=simple
$ cd egg-example
$ npm i
啓動項目:
$ npm run dev
$ open localhost:7001
更多操作查看官方文檔。
2. 下載依賴:
安裝puppeteer
:
$ npm i puppeteer -S
3. 編寫:
egg.js 中 對於 router controller service 的使用大家可以去文檔中看一下,很簡單,這裏主要講解這麼使用puppeteer抓取頁面。
簡單介紹一下puppeteer
使用:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.example.com');
await page.screenshot({path: 'example.png'});
await page.pdf({path: 'example.pdf', format: 'A4'});
await browser.close();
})();
進入正題:
目標:抓取免費代理ip網站,ip列表數據並保存到本地。
網址:http://www.ip3366.net/
那麼,開始吧。
// service 增加方法 (egg.js中,推薦將查詢類型操作放在service中)
async spider() {
const browser = await puppeteer.launch({
headless: true, // 使用無頭瀏覽器抓取
});
const page = await browser.newPage();
// 設置客戶端
await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36');
await page.goto('http://www.ip3366.net', {
waitUntil: ['domcontentloaded']
});
await page.screenshot({path: 'static.png'});
await browser.close();
return 'success';
}
通過curl
調用接口後可看到本地保存的static.png圖片,證明已經抓取到網站了。
開始抓取數據,首先查看HTML
結構:
可以看到table
在一個id爲list
的div中。
// 繼續剛纔代碼
async spider() {
const browser = await puppeteer.launch({
headless: true, // 使用無頭瀏覽器抓取
});
const page = await browser.newPage();
// 設置客戶端
await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36');
await page.goto('http://www.ip3366.net', {
waitUntil: ['domcontentloaded']
});
await page.screenshot({path: 'static.png'});
const data = await page.evaluate(() => {
var storage = [];
// 單頁爬取
var $table = $('#list table tbody');
if ($table.length) {
$table.find('tr').each(function (index, item) {
if (index !== 0) {
var $td = $(item).find('td');
storage.push({
ip: $td.eq(0).html(),
port: $td.eq(1).html(),
location: $td.eq(5).html(),
});
}
});
}
return storage;
});
await browser.close();
return JSON.stringify(data);
}
來看看結果:
接下來把數據保存到本地文件中,具體代碼就不發上來了,大家有興趣可以看一下我的倉庫。
該項目現在還在開發,大家可以持續關注一下~
https://gitee.com/unstorm/unstorm-spider
有什麼意見或者建議大家可以issues提給我。