# 2022-11-13 第一天 Python網路爬蟲應用實務班上課記錄
###### tags: `python` `爬蟲`
## 第一行程式碼
```python=
print('Hello Python')
```
## `print()`輸出用的函式
```python=
print('Hello Python1', end='')
print('Hello Python1', end='==')
print('今天天氣很好')
print()
print('H1','H2','H3','H4', sep='') # 字串 (參數) , print(參數) => 函式(參數)
print('asf\njalkfd\njlakfdjlajfladjfladjf')
```
## 輸入
```python=
a = input('請隨意輸入文字:') # =是指派的意思(指派運算子), 把右邊的資料至派給左邊的變數(把右邊的資料存到左邊的記憶體空間)
# 這裡是註解
print('你剛剛輸入的資料是:', a)
```
## 資料型態
```python=
print('Hello', 56 + 4)
print('Hello', '56' + '4') # 型態不同,無法進行運算, 串接
t = type(56) # int=整數型態(integer)
print(t)
# 當變數被重複複製派的時候,舊的資料會被覆蓋
t = type('56') # str=字串型態(string)
print(t)
t = type(3.4) # float=浮點數(小數)型態
print(t)
t = type(True) # bool=布林型態(boolean), 只會是True(真/成立)或False(假/不成立)
print(t)
```
## 字串
```python=
print('I\'m Aaron') # \為轉義符號(字元)
print("I'm Aaron") # \為轉義符號(字元)
print('I"m Aaron') # \為轉義符號(字元)
print('I\\m Aaron') # \為轉義符號(字元)
# \'
print('\\\'')
# f-string(f字串), 格式化字串
name = input('請入你的名字:')
age = input('請輸入你的年齡:')
print('你的名字是:', name, ', 年齡', age, '歲')
print(f'你的名字是: {name}, 年齡: {age}歲')
```
## 型態轉換
```python=
# 型態轉換
n = input('請輸入一個數字:') # 只要是input()函式接收到的資料,一律都是自串
n = int(n) # 將n轉型成int型態並存到n變數
print(n + 1)
```
```python=
# 型態轉換
# Ctrl + /
# n = input('請輸入一個數字:') # 只要是input()函式接收到的資料,一律都是自串
# n = int(n) # 將n轉型成int型態並存到n變數
# 這行可以取代上面兩行
n = int( input('請輸入一個數字:') ) # 有裡到外的順序執行函式
print(n + 1)
```
## 小小練習
```python=
# 請寫一個程式,讓使用者輸入兩個數字之後,相加,顯示結果在畫面上
a = int(input('輸入a數字:'))
b = int(input('輸入b數字:'))
print(a + b)
```
## 字串轉型
```python=
# int str float bool
print(str(3) + str(4))
```
## 算術運算子
```python=
# 算術運算
# 四則運算: + - * /
print(8 + 2)
print(8 - 2)
print(8 * 2)
print(8 / 2, type(8 / 2))
print(8 ** 2) # 次方(指數運算)
print(16 // 3) # 除法運算,保留整數結果
print(16 % 3) # 除法運算,保留餘數
print(999 % 2)
# 字串
print('aaron' + '18')
print('aaron' * 3)
```
## 比較運算子
```python=
# 比較運算子, 運算結果必為布林值(True, False, 請注意大小)
# > 大於
# < 小於
# >= 大於或等於
# <= 小於或等於
# == 等於
# != 不等於
print(3 > 4) # False
print(6 < 7) # True
print(9 >= 3) # True
print(5 <= 2) # False
print(8 <= 8) # True
print(8 == 8) # True
print(7 != 9) # True
print(999 != 999) # False
```
## 指派運算子
```python=
# 指派運算子
a = 3
print(a)
a = a + 8
print(a) # 11
a += 8 # 等同於a = a + 8
print(a) # 19
# -= *= /* **= //* %=
a = 8
a %= 2 # a = a % 2
print(a)
```
## 邏輯運算子
```python=
# 邏輯運算子 and or not
# True跟False
print(True and True) # True
print(True and False) # False
print(False and True) # False
print(False and False) # False
print(True or True) # True
print(True or False) # True
print(False or True) # True
print(False or False) # False
print(not True) # Falase
print(not False) # True
```
## 小小練習
```python=
print(7 > 8) # False
print(9 != 9) # False
print(3 >= 8) # False
print('7' == '8') # False
# 當比較運算子跟邏輯運算子同時出現,比較運算子會先做運算,然後才做邏輯運算
print(3 > 8 and 9 < 5) # False and False => False
print(8 == 8 or 8 != 8) # True or False => True
print(66 > 77 and 66 < 77) # False and True => False
print(not 9 != 8) # not True => False
```
## 群集資料型態
#### list
```python=
# 基本資料型態(一個變數只能存放一筆資料), int, str, float, bool
# 群集資料型態(一個變數可以存放一堆資料), list, set, dict, tuple
a = [] # 一個空的list, 沒有資料
a = [1, 2, 3, 4] # 一個list, 裡面有4筆int型態的資料
print(a)
print(a[0]) # 取出list裡面的第一筆資料, 0為資料的索引值
print(a[3]) # 第四筆資料
# print(a[5]) # 錯誤: 索引值不得超出資料範圍
a = ['aa', 99, True, 8.3, [3, 4] ]
print(a[2])
print(a[3])
print(a[4][1])
print('原始內容:', a)
a[1] = 8888
a.append(345) # 呼叫list的append方法(方法有帶小括號)
a.remove('aa') # 指定內容刪除資料
print('更新後的內容:', a)
a.reverse()
print('更新後的內容:', a)
# 群集資料通用指令跟函式(del, len(), in)
del a[0] # 指定位置刪除資料
print('更新後的內容:', a)
b = len(a) # 取得list的資料長度
print(f'a裡面有{b}筆資料')
print(8.3 in a) # 用來判斷資料是否存在於群集資料中
print('8.3' in a) # 用來判斷資料是否存在於群集資料中
```
#### set
```python=
# 基本資料型態(一個變數只能存放一筆資料), int, str, float, bool
# 群集資料型態(一個變數可以存放一堆資料), list, set, dict, tuple
# set裡面的資料不會重覆; set不保證資料存放順序,所以無法使用索引值來取得特定資料
a = {1, 2, 3}
print(a)
a = {1, 2, 3, 3, 2, 1}
print(a)
print(len(a))
a.add('5')
a.add('5')
# a.add([1, 2, 3]) # list, set, dict無法存到set裡面去
a.remove(2)
print(a)
print(1 in a)
# del無法使用在set上, 因為set沒有索引值
```
#### dict(字典)
```python=
# 基本資料型態(一個變數只能存放一筆資料), int, str, float, bool
# 群集資料型態(一個變數可以存放一堆資料), list, set, dict, tuple
# dict字典的每一筆資料都是由key(鍵)和value(值)組成
a = { 'key':'value', 3:99, 'test':True }
print(a)
# 透過key取得字典的特定資料value
print(a['key'])
print(a[3])
# 新增資料
a['key'] = 'test'
a['ok'] = 9999 # 把資料指定給不存在的key就會新增資料
del a['test']
print(a)
print(3 in a)
print(77 in a)
print(type(a))
b = {} # 建立空字典
print(type(b))
b = set() # 只能呼叫set()函式來建立空set
print(type(b))
```
#### tuple
```python=
# 基本資料型態(一個變數只能存放一筆資料), int, str, float, bool
# 群集資料型態(一個變數可以存放一堆資料), list, set, dict, tuple
# tuple跟list用法幾乎一樣, 但tuple一經建立就無法修改內容
a = ()
a = (1, 2, 3) # 建立tuple
a = 1, 2, 3, # 建立tuple
print(type(a))
print(a)
print(a[0])
a = (1,)
a = 1, # 建立一個只有一筆資料的tuple
print(type(a))
```
#### pack與unpack
```python=
# unpack(拆解)
a = 1, 2, 3, 4, # pack打包
print(a)
a, b, c, d = a # unpack
print(a)
print(b)
print(c)
print(d)
*a, b, c = (1, 2, 3, 4)
print('a=', a)
print('b=', b)
print('c=', c)
aa = 4
bb = 5
# 變數內容
# temp = aa # 傳統資料交換方式
# aa = bb
# bb = temp
aa, bb = bb, aa # 使用unpack訪式來做變數內容的交換
print('aa=', aa)
print('bb=', bb)
```
## 索引切片
```python=
# 索引切片運算子
a = [1, 65, 88, 3, 92, 100, 26, 5, 89, 57] # <--
a[1] # 取得第二筆
# [start:end(但不包含終點索引):step]
print(a[1:4])
print(a[:3])
print(a[:])
print(a[3:])
print(a[:-1])
print(a[-3:-1])
print(a[::2])
print(a[-2:-4:-1]) # 當step為負數時,切片的順序為由後至前,start和end索引也要反過來提供
```
## 快篩資訊
到政府的開放資料(open data)平台下載全台灣所有快篩販售點的剩餘量:
網址:https://data.gov.tw/dataset/152408

> **備註:**
> 下載的檔案格式為CSV檔,可用Excel打開;也可以用記事本打開,會見到所有的資料都是由逗號隔開為一個一個的欄位。
#### 需求
1. 解析從政府開放資料平台下載的CSV格式檔案
2. 找出藥局名稱有「人生」兩個字的藥局並顯示剩餘量。
```python=
import csv # 引入外部的csv模組
with open('Fstdata.csv', encoding='utf-8') as csvfile: # <-- 冒號很重要
rows = csv.reader(csvfile) # 透過csv模組將檔案內容轉成list(兩層)
rows = list(rows) # 將資料型態轉成list
for row in rows: # 透過for迴圈一筆一筆資料來處理, row為每一列快篩資料
if '人生' in row[1]: # 判斷row這個list內索引1的資料有沒有「人生」兩個字
print(row[1], row[7]) # 每一筆藥局資料
```
**說明:**
1. 第一行:`import csv`為了要解析CSV檔案內容,所以引入了外部csv模組
2. 第三行:使用關鍵字with來處理操作檔案的細節,函式open()用來打開一個檔案,第一個參數為檔案名稱,也就是從政府開放資料平台下載的檔案「Fstdata.csv」,第二個參數`encoding='utf-8'`用來指定打開檔案後解碼文字的方式,因為下載的快篩檔案為UTF-8(國際編碼)格式,所以這邊需指定這個參數。`as`關鍵字後面則是存檔打開後的存放檔案的變數。
3. 第四行:呼叫csv模組內的reader()方法來解析csv檔案。
4. 第五行:將解析後的資料轉成list,這是一個兩層的list,一個大list內存有許多小list,這個小list就是剛剛Excel打開時的每一筆快篩剩餘量的資料。
5. 第七行:使用for-in迴圈來一筆一筆取的list內的每一筆快篩資料,`row`為一個list
6. 第八行:判斷每一筆快篩資料list內的第二個欄位的值是否有包含「人生」兩個字,第2個欄位即是藥局名稱。
7. 第九行:印出藥局名稱(row[1])和該藥局的快篩剩餘量(row[7]),分別在第2和第8個個欄位。
## 課後練習
#### 基本型態、運算子
1. Python數值型態有哪4種?
**答:**
```
```
2. 字串可以使用哪些算術運算子?
**答:**
```
```
3. 在字串裡可以使用什麼轉譯字來換行?
**答:**
```
```
4. 何謂r字串?
**答:**
```
```
5. Python有哪幾種格式化字串的方式?
**答:**
```
```
6. `4 < 0`的運算會產生甚麼結果?
**答:**
```
```
7. Python內如何使用註解?
**答:**
```
```
8. 該怎麼去掉`4.5`的小數點? 請寫出程式碼。
**答:**
```
```
9. 請用指派運算子寫出`a = a + 99`的精簡寫法。
**答:**
```
```
10. 何謂轉型? 請舉例以程式碼示範將字串轉型為整數。
**答:**
```
```
#### 群集型態
1. Python有哪4種群集型態?
**答:**
```
```
2. 要如何取得['aaron', 'andy', 'abner']清單內的'abner'這筆資料? 請寫出程式碼。
**答:**
```
```
3. 該怎麼判斷某個元素是否存在於list當中?
**答:**
```
```
4. `a = {}`會建立出甚麼群集型態?
**答:**
```
```
5. 哪兩種方法可以取得dict內的值?
**答:**
```
```
6. 要刪除tuple內某一筆資料有哪些方法?
**答:**
```
```
7. `a, b, c = (1, 2, 3)`這是資料的pack還是unpack?
**答:**
```
```
8. 如何用一行程式碼產生一個1~100之間偶數的`list`?
```
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100]
```
**答:**
```
```
9. 如何取出下面set()所有的數字並加總後使用print()函式輸出。
```
my_set = {28, 37, 16}
```
**答:**
```
```
10. 有一個`list`為:`['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']`,請問:
a. 如何使用切片得到:`['b', 'd', 'f', 'h', 'j']`的結果?
**答:**
```
```
b. 如何使用索引切片得到:`['i', 'j', 'k']`的結果?
**答:**
```
```
c. 如何使用索引切片得到: `'c-b-a'`的結果?
**答:**
```
```
d. 如何使用索引切片得到:`'kakakaka'`的結果(搭配算術運算子)?
**答:**
```
```
> k為最後一個值,a為第一個值。
11. `remove()`方法和`del`都可以用來刪除`list`的一個元素,請問這兩個刪除元素的方式有什麼差別?
**答:**
```
```
12. 有一個字串`list`為:`data = ['aaron', 'andy', 'apple', 'amber', 'aaron', 'abner']`,其中`'aaron'`出現了兩次,如何從該`list`中移除所有的`'aaron'`字串?
**答:**
```
```
13. 有兩個`list`資料,一個為學生姓名,一個為對應的每個學生成績,請問該如何將這兩個`list`資料配對後合併成一個`dictionary`,例如:
將:
```
names = ['aaron', 'andy', 'amber', 'apple', 'abner']
scores = [100, 90, 60, 80, 50]
```
變成:
```
{'aaron': 100, 'andy': 90, 'amber': 60, 'apple': 80, 'abner': 50}
```
**答:**
```
```
14. 如何用一行程式碼,就將`data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`就將這個`list`的第一個植根最後一個值分別存放到`first`和`last`變數當中?
**答:**
```
```
> first將會是0,last為9