步驟一:安裝必要模塊
(1)cheerio模塊 ,一個類似jQuery的選擇器模塊,分析HTML利器。
(2)request模塊,讓http請求變的更加簡單
(3)mysql模塊,node連接mysql的模塊
npm i cheerio request mysql -D
步驟二:分析爬取網址的內容
目標URL:
http://zzk.cnblogs.com/s/blogpost?Keywords=%E6%B8%B8%E6%88%8F,游戲其實被編碼成了%E6%B8%B8%E6%88%8F
分析:
var url = 'http://zzk.cnblogs.com/s/blogpost?Keywords=' + key + '&pageindex=' + page;
如果key是中文,是會抓取不到任何數據,用JS函數url = encodeURI(url);轉換一下就好。
用"pageindex="出現的位置加上本身長度即得到頁數
page = nextUrl.slice(nextUrl.indexOf('pageindex=') + 10);
indexof是返回子串在母串的第一個位置,沒有則-1,區分大小寫
步驟三:創建數據表
(1)啟動 mysql
mysql -uroot -p123456
root是mysql用戶名,123456是密碼
(2)創建 database 數據庫
create database spider_data;
(3)查看 所有的 database 數據庫
show databases;
(4)進入 數據庫
use spider_data;
(5)創建 table 表單
create table blog( id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY, title VARCHAR(100) NOT NULL, href VARCHAR(100) NOT NULL, author VARCHAR(100) NOT NULL, time DATE, view INT(5) NOT NULL );
MySQL數據類型包括:整型、浮點型、日期類型、字符型,這里用表格的方式詳細說明每個數據類型,這些只要記住常用的即可,需要再查閱。
整型
| 數據類型 | 存儲范圍 | 字節 |
|---|---|---|
| TINYINT | 有符號值:-128 到 127(-2727到2727) 無符號值:0到255(0到2828) |
1 |
| SMALLINT | 有符號值:-32768 到 32767(-215到215215到215) 無符號值:0到65535(0到216216-1) |
2 |
| MEDIUMINT | 有符號值:-8388608 到 8388607(-223到223223到223) 無符號值:0到16777215(0到224224) |
3 |
| INT | 有符號值:-231到231231到231 無符號值:0到232到232-1 |
4 |
| BIGINT | 有符號值:-263到263263到263 無符號值:0到264到264-1 |
8 |
浮點型
| 數據類型 | 精度 |
|---|---|
| FLOAT[(M,D)] | 小數點后6-7位(常用) |
| DOUBLE[(M,D)] | 小數點后14-15位 |
日期時間類型
| 日期類型 | 存儲空間(字節) | 日期格式 | 范圍 |
|---|---|---|---|
| datetime | 8 | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 |
| timestamp | 4 | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 ~ 2038 |
| date | 3 | YYYY-MM-DD | 1000-01-01 ~ 9999-12-31 |
| year | 1 | YYYY | 1901~2155 |
| time | 2 | HH:MM:SS | -838:59:59 ~ 838:59:59 |
字符型
| 列類型 | 說明 |
|---|---|
| CHAR(M) | M個字節,0<=M<=255,固定長度 |
| VARCHAR(M) | L+1個字節,其中L<M且0<M<65535,可以小於定於長度M |
| TINYTEXT | L+1個字節,其中L<2828 |
| TEXT | L+2個字節,其中L<216216 |
| MEDIUMTEXT | L+3個字節,其中L<224224 |
| LONGTEXT | L+4個字節,其中L<232232 |
| ENUM('value1','value2') | 枚舉,1或2個字節,取決於枚舉的個數(最多216216-1個值) |
| SET('value1','value2') | 集合,1,2,3,4,8個字節,取決於成員個數 |
(6)查看 當前數據庫下的 數據表
show tables;
(7)查看表結構
desc blog;
步驟四:代碼
/**
* 將node爬取到的數據,保存到mysql數據庫中
*/
var request = require('request');
var cheerio = require('cheerio');
var mysql = require('mysql');
// 創建數據庫連接
var db = mysql.createConnection({
host: '127.0.0.1',
user: 'root',
password: '123456',
database: 'spider_data'
});
db.connect();
// 請求數據
function fetchData(key, page) {
var url = 'http://zzk.cnblogs.com/s/blogpost?Keywords=' + key + '&pageindex=' + page;
//用JS的全局對象函數,作為URI編碼,不然中文,空格等抓取不到
url = encodeURI(url);
request(url, function(err, res) {
if (err) return console.log(err);
var $ = cheerio.load(res.body.toString());
var arr = [];
//解析HTML代碼
$('.searchItem').each(function() {
var title = $(this).find('.searchItemTitle');
var author = $(this).find('.searchItemInfo-userName a');
var time = $(this).find('.searchItemInfo-publishDate');
var view = $(this).find('.searchItemInfo-views');
var info = {
title: $(title).find('a').text(),
href: $(title).find('a').attr('href'),
author: $(author).text(),
time: $(time).text(),
view: $(view).text().replace(/[^0-9]/ig, '')
};
arr.push(info);
//打印
console.log('~~~~~~~~~~~~~~~~~~~~~~~ 輸出開始 ~~~~~~~~~~~~~~~~~~~~~~~');
console.log(info);
console.log('~~~~~~~~~~~~~~~~~~~~~~~ 輸出結束 ~~~~~~~~~~~~~~~~~~~~~~~');
//保存數據
db.query('insert into blog set ?', info, function(err, result) {
if (err) throw err;
if (!!result) {
console.log('插入成功');
console.log(result.insertId);
} else {
console.log('插入失敗');
}
});
});
//下一頁
var nextA = $('.pager a').last(),
nextUrl = '';
if ($(nextA).text().indexOf('Next') != -1) {
nextUrl = nextA.attr('href');
page = nextUrl.slice(nextUrl.indexOf('pageindex=') + 10);//"pageindex="出現的位置加上本身長度得到頁數
setTimeout(function() {
fetchData(key, page);
}, 2000);
} else {
db.end();
console.log('結束,爬取完所有數據');
}
});
}
// 調用
fetchData('游戲開發', 1);
.
