--- tags: bahamut-pie, side project --- # bahamut-pie - chapter2: web crawler🐞 前端要練手最缺的就是資料,最簡單的方式就是接open data 而 Node.js 讓前端有辦法用 javascript 撰寫爬蟲程式放在 server 運行 ## build a crawler 初步的想法是做一個API,被 call 的時候就去爬取網頁資料回傳 不確定這個做法適不適當,但先做再說吧 ### how to? 1. 用 request 把要爬的頁面 html 拿來 2. 針對頁面用 cheerio 抓取元素,用法和 jquery 選取一樣 3. 從選取到的元素中提取資料,組成 json 回傳 **以下為範例,並非實際的code** ```javascript= // 1. 把文章列表的 html 拿來 request(url, (err, res, body) => { // 2. 拿到 html (body),用 cheerio 初始化 const $ = cheerio.load(body); // 3. 遍歷頁面中的 a.article-link ,從元素中取資料並重組 $('.article-link').each(function(i,el) { return{ title: $(el).text(), url: $(el).attr('href') }; }); }) // 4. 單筆資料長這樣,經過上面的遍歷就可以組合成陣列 { title: '文章標題', url: 'https://文章的網址' } ``` #### note🤏 做爬蟲之前要看一下目標網站的 html 結構,巴哈姆特雖然結構稍醜但還算單純好爬 像是表單頁、無限滾動甚至防爬蟲的網站就要用更複雜的做法 ### API化 前端對API應該不陌生,帶參數 call API 會回傳不同的資料 e.g. 要查 handred800 的文章數據就在API網址中 加入id=handred800 所以要做出接口來接收參數 **以下為範例,並非實際的code** ``` javascript // API 的入口,用 ajax call 這支 API 會從這邊開始 app.get("/", async (req, res) => { // 從請求中提取使用者ID的參數 const userId = req.query.id; const url = `http://home.gamer.com.tw/?owner=${userId}`; // 呼叫前面那段爬蟲程式 const articles = await articleCrawler.getArtcles(url); // 跨域請求無限制 res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); // 最後把 articles 整個傳回去 return res.json(data); } ``` 沒用過 Node.js 應該看不懂,來看看 API 完成後怎麼 call 應該能懂 假設我的程式碼放在 https://crawler-api.com 這個位址 ``` javascript // ajax call API fetch('https://crawler-api.com/?id=handred800') .then((res) => res.json()) // 轉 json 格式 .then((data) => { console.log(data); // 拿到資料囉! }) ``` ## depoly on Heroku 部屬到 server = 把程式碼放在某台電腦上不眠不休的運行 以 API 來說就是等著隨時被 call Heroku 用起來很容易,可以用下指令的方式上傳檔案到 server 我是連結 github repo,當 push 的時候會自動重新部屬 相當方便 免費方案有次數限制&休眠機制,但對小專案來說很夠用 文末附上完成品,readme 有 API 的使用方式,搭配著看會好懂很多 [**github page**](https://github.com/handred800/bahamut-home-article-cralwer)