2018 中興大學資工營

爬蟲程式

日期/ 2018/07/14

講者/ YoYo           

連結/ bit.ly/2018NCHUCSECamp

講者介紹

 

中興資工大四

中興資訊社前社長

facebook.com/it.nchu

洪浩祐 YoYo

課程大綱

  • 簡介爬蟲
  • HTTP
  • [try 0] Javascript & node.js
  • [try 1] 網頁封包分析
  • request
  • [try 2] 爬 ptt 首頁下來
  • DOM、$
  • cherrio
  • [try 3] 分類出看板名以及連結

什麼是爬蟲?

網路爬蟲啦

動物界的朋友?

Skyscanner 機票比價網

時刻表、搶票機

他們怎麼辦到的?

就是爬蟲

HTTP

Hypertext Transfer Protocol

瀏覽器

模擬使用者的行為

對網頁伺服器收發

POST/GET request

瀏覽器

Javascript

第一次聽嗎

其實你每天都有接觸

右鍵 > 檢查

那個就會彈出來了

你就可以在這裡打

不要問我為什麼是黑色的

簡介

HyperText Markup Language

超文件標示語言

網頁的骨架

網頁瀏覽器可以讀取HTML檔案,並將其彩現成視覺化網頁。

HTML描述了一個網站的結構,使之成為一種 標示語言 而非程式語言。

Cascading Style Sheets

層疊樣式表

網頁的外觀

使用 CSS 來決定文件內容的顏色、字型、排版等顯示特性​

JavaScript

網頁的大腦

一種高級程式語言,需通過解釋執行

Node.js

Node.js 大部分基本模組都用 JavaScript 語言編寫。在 Node.js 出現之前,JavaScript 通常作為用戶端程式設計語言使用,以 JavaScript 寫出的程式常在用戶的瀏覽器上執行。Node.js 的出現使 JavaScript也能用於伺服器端編程。Node.js 含有一系列內置模組,使得程式可以脫離 Apache HTTP Server 或 IIS,作為獨立伺服器執行。

[try 0]
上手 Javascript

👉🏻 bit.ly/NCHUCSECamp-JS 👈🏻

你需要做的:下載 node
821應該已經有了

點擊下方連結,開啟奇幻旅程

[try 1]
網頁封包分析

以 Yahoo 字典為例

request

開源的網頁封包發送套件

很舒服的寫 code

先將套件載下

  1. 先建立一個專案資料夾

  2. npm install request

  3. 好了!!!

範例

const   request   =   require('request');

request('https://www.google.com', (error, response, body) => {
 console.log('error: ', error);
 console.log('sratusCode: ', response   &&   response.statusCode);
 console.log(body);
});

執行看看 node + [檔名]

[try 2]
試著爬 ptt 首頁

執行看看 node + [檔名]

將剛剛的範例網址換成 PTT 首頁囉

https://www.ptt.cc/bbs/index.html

爬下來的東西

如何存起來?

指令:node [檔名.js] > [新檔名.html] 

看起來好醜

原始碼這麼一大坨
怎麼取出想要的資訊

  1. 人工切割到脫窗 - 什麼時代了

  2. 正則表達式 - 你不懂,我也不會

  3. cheerio - 好棒棒

DOM

文件物件模型(Document Object Model, DOM)是 HTML、XML 和 SVG 文件的程式介面。它提供了一個文件(樹)的結構化表示法,並定義讓程式可以存取並改變文件架構、風格和內容的方法。DOM 提供了文件以擁有屬性與函式的節點與物件組成的結構化表示。節點也可以附加事件處理程序,一旦觸發事件就會執行處理程序。 它將網頁與腳本或程式語言連結在一起。

打開任一個頁面檢查

$

錢錢嗎?

No, 是 JQuery 的 $

跨瀏覽器的 JS 函式庫
簡化 HTML 與 JavaScript 之間的操作

用 JQuery 對 DOM 元素操作

// 選取所有 tag 為 'a' class 為 'board' 的元素(有一個以上,陣列回傳)
$('a.board')

// 從陣列拿某一個出來
$('a.board')[18]

// 選取所有 tag 為 'a' class 為 'board' 的元素
// 並尋找 class 為 'board-name' 的子元素(有一個以上,陣列回傳)
$('a.board').find('.board-name')

// 將某一個 class 為 'board-name' 的元素文字取出
$($('a.board').find('.board-name')[18]).text()

仿造 JQuery 方式

操作 DOM 物件的 node.js 套件

舉個例子
新增一個 js 檔案

const cheerio = require('cheerio')
const $ = cheerio.load('<h2 class="title">Hello world</h2>')

$('h2.title').text('Hello there!')
$('h2').addClass('welcome')

console.log($.html())
//=> <h2 class="title welcome">Hello there!</h2>
//一樣存檔後用 node + 檔名執行看看

[try 3]

分類首頁看板及連結

範例

const   request   =   require('request');
const   cheerio   =   require('cheerio');
const   fs        =   require('fs');

let   HotBoardsJson   = [];
let   url   =   'https://www.ptt.cc'

request(url   +   '/bbs/index.html', (error, response, body) => {
 console.log('error: ', error);
 console.log('statusCode: ', response   &&   response.statusCode);

 // console.log('body: ', body);
 var   $   =   cheerio.load(body);
 boardArr   =   $('a.board');
    
 for (var i = 0; i < boardArr.length; i++) {
     boardName  =  $($(boardArr[i]).find('.board-name')).text();
     boardClass =  $($(boardArr[i]).find('.board-class')).text();
     boardLink  =  url + $(boardArr[i]).attr('href');
     HotBoardsJson.push({ boardName:   boardName, boardClass:   boardClass, boardLink:   boardLink })

     console.log(`${boardName}\n>> ${boardLink}\n>> 分類:${boardClass}\n`);
  }
  // 把爬下來的東西存起來法2
  fs.writeFile('HotBoards.json', JSON.stringify(HotBoardsJson), function (err) {
    if (err)
        console.log(err);
    else
        console.log('File '   +   'HotBoards.json'   +   'written!');
  })
  console.log('共 '   +   HotBoardsJson.length   +   ' 篇\\n');
});

謝謝各位💕
放飯啦🍱

2018 中興資工營-爬蟲社課

By Hao-You Hung

2018 中興資工營-爬蟲社課

2018 中興大學 資工營 爬蟲課程

  • 833