爬蟲應該遵循:robots 協議html
引用百度百科:node
網絡爬蟲(又稱爲網頁蜘蛛,網絡機器人,在 FOAF 社區中間,更常常的稱爲網頁追逐者),是一種按照必定的規則,自動地抓取萬維網信息的程序或者腳本。另一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。ios
通俗的講就是經過機器自動地獲取想要的信息,當你訪問一個網站,發現有不少好看的圖片,因而你會選擇右鍵保存到本地,當你保存了幾張以後你會想我爲何不能寫個腳本,自動的去下載這些圖片到本地呢?因而爬蟲誕生了......npm
最終效果: json
1 目錄axios
┌── cache
│ └── img 圖片目錄
├── app.js
└── package.json
複製代碼
2 安裝依賴數組
npm i axios --save
複製代碼
npm i cheerio --save
複製代碼
npm i fs --save
複製代碼
爬取某戶外網站,爬取首頁推薦的圖片並下載到本地 網絡
1 流程分析2 編寫代碼 axios 拿到 html 片斷 分析發現該圖片在'newsimg'塊裏,cheerio 使用跟 jq 基本沒什麼區別,拿到圖片標題和下載連接 app
const res = await axios.get(target_url);
const html = res.data;
const $ = cheerio.load(html);
const result_list = [];
$('.newscon').each(element => {
result_list.push({
title: $(element).find('.newsintroduction').text(),
down_loda_url: $(element).find('img').attr('src').split('!')[0],
});
});
this.result_list.push(...result_list);
複製代碼
已經拿到一個下載連接數組,接下來要作的是遍歷該數組,發送請求而後用 fs 保存到本地dom
const target_path = path.resolve(__dirname, `./cache/image/${href.split('/').pop()}`);
const response = await axios.get(href, { responseType: 'stream' });
await response.data.pipe(fs.createWriteStream(target_path));
複製代碼
3 請求優化 避免太頻繁請求會被封 ip,比較簡單的方法有幾個:
class stealData {
constructor() {
this.base_url = ''; //要爬取的網站
this.current_page = 1;
this.result_list = [];
}
async init() {
try {
await this.getPageData();
await this.downLoadPictures();
} catch (e) {
console.log(e);
}
}
sleep(time) {
return new Promise((resolve) => {
console.log(`自動睡眠中,${time / 1000}秒後從新發送請求......`)
setTimeout(() => {
resolve();
}, time);
});
}
async getPageData() {
const target_url = this.base_url;
try {
const res = await axios.get(target_url);
const html = res.data;
const $ = cheerio.load(html);
const result_list = [];
$('.newscon').each((index, element) => {
result_list.push({
title: $(element).find('.newsintroduction').text(),
down_loda_url: $(element).find('img').attr('src').split('!')[0],
});
});
this.result_list.push(...result_list);
return Promise.resolve(result_list);
} catch (e) {
console.log('獲取數據失敗');
return Promise.reject(e);
}
}
async downLoadPictures() {
const result_list = this.result_list;
try {
for (let i = 0, len = result_list.length; i < len; i++) {
console.log(`開始下載第${i + 1}張圖片!`);
await this.downLoadPicture(result_list[i].down_loda_url);
await this.sleep(3000 * Math.random());
console.log(`第${i + 1}張圖片下載成功!`);
}
return Promise.resolve();
} catch (e) {
console.log('寫入數據失敗');
return Promise.reject(e)
}
}
async downLoadPicture(href) {
try {
const target_path = path.resolve(__dirname, `./cache/image/${href.split('/').pop()}`);
const response = await axios.get(href, { responseType: 'stream' });
await response.data.pipe(fs.createWriteStream(target_path));
console.log('寫入成功');
return Promise.resolve();
} catch (e) {
console.log('寫入數據失敗');
return Promise.reject(e)
}
}
}
const thief = new stealData('xxx_url');
thief.init();
複製代碼