# 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`