# FDCSC110 Feb25 Handout - Web Crawler I --- ## 複習上學期的東西 - [講義連結](https://hackmd.io/@revcoding/fdcsc_110_handouts) ## 本次上課範例程式碼 - [Github Link](https://github.com/revival0728/FudanHighSchool-110CSC/tree/master/Web_Crawler/for_imgur) ## 物件導向 (OOP) 只要開始實作一些比較大型的程式時, 就一定會用到的觀念, 甚至一些遊戲引擎把 **OOP** 設定成基本架構, 例如 `Unity`、`Godot` 等。 用簡單一點的方式來解釋的話, 就是把相關的變數、函數打包成一個物件, 這樣做的好處有很多, 例如 **避免重名**、**方便維護** 等。 以下我們來看個範例。 今天要記錄每位學生的段考成績, 需要紀錄的資訊有 **姓名**、**學號**、**數學成績** 和 **自然成績**, 如果不使用 **OOP** 的程式碼如下 ```python= name = ['John', 'Tree', 'Hank'] ID = ['911001', '911002', '911003'] math_score = [100, 95, 90] science_score = [90, 95, 100] ``` 這樣的程式碼乍看之下還可以, 但是等到實際操作時會非常不直覺, 因為會是用索引值來操作, 其實這個方法可以用 `dict` 來解決 ```python= scores = { 'John': { 'ID': '911001', 'math_score': 100 'science_score': 90 }, ... } ``` 這樣操作起來會好很多, 因為是用生活中的名詞來取值, 但是有一個缺點——不易宣告, 這個辦法也很好解決, 寫一個打包函數就好了。 ```python= def score_packer(ID: str, math_score: int, science_score: int): return { 'ID': ID, 'math_score': math_score, 'science_score': science_score } ``` 以上看到的一連串變化就是 **OOP** 的前身, 其實只要把打包函數、`dict` 包進一個 `class` 裡面就完成 **OOP** 的實現了。 ```python= class score: def __init__(self, name: str, ID: str, math_score: int, science_score: int): self.name = name self.ID = ID self.math_score = math_score self.science_score = science_score scores = [ score('John', '911001', 100, 90), score('Tree', '911002', 95, 95), score('Hank', '911003', 90, 100) ] ``` 這學期的程式碼都會有 **OOP** 版本的, 想要學的可以去看看。 ## requests 這是 `Python` 一個很適合用於爬蟲的套件, 因為篇幅我們只講會用到的東西, 想要研究的可以[點選連結](https://docs.python-requests.org/en/latest/)去自習。 ### 匯入模組 ```python= import requests as rqs ``` ### get() ```python= response = rqs.get('https://imgur.com/search?q=hololive') ``` 這個函數會回傳造訪網頁的所有結果, 爬蟲只會用到裡面的 `.text` 也就是 `html` ## bs4 - BeautifulSoup 這是 `Python` 裡面用來分析大量字串的套件, 一樣很適合用於爬蟲, 想要更深入研究的可以[點選連結](https://www.crummy.com/software/BeautifulSoup/bs4/doc/) ### 匯入模組 ```python= from bs4 import BeautifulSoup as bsp ``` ### 宣告 ```python= html = bsp(html_text, 'html.parser') ``` ### find_all(name, attrs, recursive, string, **kwargs) ```python= element = html.find_all(name='div', attrs={'class', 'cards'}) ``` 這個函數很重要, 幾乎就是整個爬蟲的靈魂, 這次會用到的只有引數 `name` 和 `attrs` 而已。 `name` 抓的就是 `html` 中的元素類型 `attrs` 抓的就是每個元素裡面的資料,像是 `class`、`color`、`type`、`id`、`data` 等 由於是找出所有符合的結果, 所以會回傳 `list`, 只要數一下你要的元素在第幾個就好。 ## Pillow - Image 這個是用來顯示圖片的模組, 是這次實作特別需要用到的, 跟爬蟲無關, 想要深入學習的請[點選連結](https://pillow.readthedocs.io/en/stable/reference/Image.html?highlight=image) ### 匯入模組 ```python= from PIL import Image ``` ### 宣告 ```python= image = image.open(res_pic.raw) ``` ### show() ```python= image.show() ``` 這個函數是用來把圖片顯示到畫面的, 等等實作時會就會理解了, 不過有個缺點是只要開啟了, 就沒辦法用程式關閉, 因為主導權已經轉移給作業系統了。 ## 實作環節 - imgur.com 的爬蟲 這次需要用到的新東西非常少, 希望各位能好好的學起來, 做出來的東西蠻酷的。 眾所周知, `imgur` 是一個充滿圖(好)片(香)的網站, 因此只要能把圖片爬出來, 就相當於掌握了整個網站。 ### Step1 觀察 html 打開 `imgur` 後搜尋 `hololive`, 對圖片選右鍵後打開檢查頁面, 右邊就會出現 `html`, 你會發現承裝圖片的元素為 `img`, 而他的母元素是一個 `div`, 一個 `div` 代表的就是一個圖片, 再往上找我們會發現再上面這個 `div` 裝著所有圖片, 我們的目標就是用 `BeautifulSoup` 把它找出來。 ### Step2 觀察網址 想爬蟲, 首先一定要有網址, 這個網址的規律很好看出來, ``` https://imgur.com/search/?q=想要查的內容 ``` 如果有空白, 就用 `+` 取代。 ### Step3 開始爬蟲 這邊就直接看程式碼就好了, - [Github Link](https://github.com/revival0728/FudanHighSchool-110CSC/blob/master/Web_Crawler/for_imgur/simple_version/for_imgur.py) 有不懂的都歡迎提問 如果不想手動安裝套件的話[點選連結](https://downgit.github.io/#/home?url=https://github.com/revival0728/FudanHighSchool-110CSC/blob/master/Web_Crawler/for_imgur/requirements.txt)來下載 `requirements.txt`