# Part 1
## 安裝
### [Python官方連結](https://www.python.org/)
* 點選 download 下載最新版本,目前是3.11.5版,下載完畢後直接安裝。

### [Anaconda官方連結](https://www.anaconda.com/download)
* 點選 Windows 版本下載,一樣下載完畢後直接安裝。
[安裝參考1](https://simplelearn.tw/anaconda-3-intro-and-installation-guide/)
[安裝參考2](https://medium.com/python4u/anaconda%E4%BB%8B%E7%B4%B9%E5%8F%8A%E5%AE%89%E8%A3%9D%E6%95%99%E5%AD%B8-f7dae6454ab6)

### 安裝後確認
* 開啟 cmd,輸入下方指令(小寫v),可進入 python "測試功能模式"。
* 若要結束此模式,可輸入 Ctrl+Z 即可跳回原來的模式。
```python=
python -v
```
* 開啟 cmd,輸入下方指令(大寫V),可查看安裝版本。
```python=
python -V
```

:::success
:bulb: **安裝完成後,先進入 python "測試功能模式"吧。**
:::
## 變數
* 變數命名可以包含以下字元
* 小寫字母
* 大寫字母
* 數字
* 底線 _
* 可以是
* aName
* Name1
* Name_of_division___DigiTech
* _HowManyGroup
* _2HappyTeam
```python=
aName = "Justin"
Name_of_division___DigiTech = "數位科技"
_HowManyGroup = 3.5
```
* 不可以是
* 3
* 3a
* 5_
* groupfunction!
* another-name
```python=
3 = "賈斯汀" #錯誤的變數命名
groupfunction! = "no idea"
```
## 基本型別
* 檢測變數型別的方法
```python=
var=0
type(var)
```
### 布林
* True, False
* 對或錯
* 相等或不相等
* 黑或白
```python=
Sleep_In_Class = False
Sleep_At_Home = True
```
#### 運算
```python=
# 運算邏輯是否相等
Sleep_In_Class == Sleep_At_Home # 運算結果是False
# 運算邏輯是否不相等
Sleep_In_Class != Sleep_At_Home # 運算結果是True
# 比較數字大小
x = 5
y = 7
#大於
x > y # 運算結果是False
#小於
x < y # 運算結果是True
#大於等於 >=
#小於等於 <=
```
### 數字
#### int
```python=
var = var + 1 #var += 1 也是一樣
print(var)
```
#### float
```python=
var = 9.9
print(var)
```
#### 數字運算
|運算子|說明|範例|結果|
|--|--|--|--|
| + | 加法 | 3 + 5 | 8 |
| - | 減法 | 3 - 5 | -2 |
| * | 乘法 | 3 * 5 | 15 |
| / | 除法 | 3 / 5 | 0.6 |
| // | 除法捨去 | 3 // 5 | 0 |
| % | 餘數 | 3 % 5 | 3 |
| ** | 次方 | 3 / 5 | 243 |
### 字串
* 如何建立
```python=
# 使用單引號
aString = '一串文字'
# 使用雙引號
aString = "一串文字"
# 單純建立一段文字
str(一串文字)
```
* 連接文字,使用"+"號
```python=
Constarin1 = "控制01-1"
Constrain2 = "控制02-1"
# 連接所有字串,結果應該是 控制01-1, 控制02-1
Full_String = Constarin1 + ", " + Constarin2
```
#### 字串處理
* 使用中括號 **[ ]** 取得字元
以 "控制12-3" 為例,字串中有6個字元,下方則代表各個字元在字串中的位置。
| pose 0 | pose 1 | pose 2 | pose 3 | pose 4 | pose 5 |
| - | - | - | - | - | - |
| 控 | 制 | 1 | 2 | - | 3 |
* 取得特定位置
```python=
Constarin1 = "控制12-3"
#取得字串位置2的字元
Constarin1[2] # 顯示1
```
> **公式:string[ 起點位置 : 終點位置 : 間隔]**
* 指定起始終點並取得一段文字
```python=
Constarin1 = "控制12-3"
#指定起始終點
Constarin1[1:4] # 顯示"制12-"
```
* 反轉字串
```python=
Constarin1 = "控制12-3"
#step倒序(-1)
Constarin1[::-1] # 顯示"3-21制控"
```
* 其他有用函式
```python=
#算長度
#用途:透過此函數計算內容長度,符合長度的內容才可以寫入資料庫
Constarin1 = "控制12-3"
len(Constarin1) # 6
#分段
#用途:透過特並符號將一大串文字分段,分段後就可以拿來做其他操作
NameString = "Mike, Julian, Lucky, Cathy"
NameString.split(',') # ['Mike', 'Julian', 'Lucky', 'Cathy']
#join 結合
NameSplitString = ['Mike', 'Julian', 'Lucky', 'Cathy']
NameString = ','.join(NameSplitString) # 'Mike,Julian,Lucky,Cathy'
#replace 替換
#用途:替換字串中的符合條件的文字
aStr = "a duck goes to rock"
aStr.replace('duck', 'lion') # 'a lion goes to rock'
#strip 剝除
#用途:移除字串前後的空白格
aSpaceStr = " haha " #前後有空格,比對關鍵字的時候會有問題,因為" haha "不等於"haha"
aSpaceStr.strip() # 移除前後空白後,結果為"haha"
# in 是否在裡面
# 用途:檢查關鍵字是否存在
CaseStr = '''經查辦理聯徵中心信用資訊查詢作業,雖已取得
客戶之聯徵查詢同意書(LNC-356),經查客戶僅向本行申請
房屋貸款、信用貸款,其同意書應僅得勾選第一項「一般授信」、
第六項、「介接查詢」。
'''
key = "同意書"
key in str # 檢查後結果為 True
```
#### 格式
```python=
thing = 'duck'
place = 'lake'
'The {} is in the {}!'.format(thing, place)
# 顯示為 The duck is in the lake!
#也可以寫成
"The " + thing + "is in the " + place
```
:::success
:bulb: **下面要開始真正來寫程式了,先來安裝vscode**
:::
## [vscode下載](https://code.visualstudio.com/)
* 點選畫面上 Download for Windows 下載最新版本,下載完畢後直接安裝。
## 容器
|資料型態|可接受多資料型態|順序|改變內容|內容重複|
|--|--|--|--|--|
| list | V | 有 | 可 | 可 |
| tuple | V | 有| 不可 | 可 |
| set | V | 無 | 可 | 不可 |
| dict | V | 有 | 可 | key值不可重複 |
### 容器表頭名詞解釋
* **可接受多資料型態**
* 意思是容器內放入任何型態的資料都是可以的,例如說list可以先放字串進去後,再放數字進去。其他高階語言不一定能支援這樣的功能,如C#的list裡,放置的都必須是同一種型態,若要放字串,就都只能放置字串。
* **順序代表**
* 這個容器是可以支援排序,通常是呼叫.sort()方法來達到。(可參考下方list其他操作)
* **改變內容**
* 意思是指容器的東西放進去之後,無法透過set的方式設定新的值,若透過其他的方法也許可以做到。
* **內容不可以重複**
* 代表每次方進去的東西是不能相同的,例如dict就不能放進去兩個相同的key值,有點類似資料庫的primary key的概念,表內是無法存在兩個相同的key在同一個欄位。
### list
* list的建立是使用[]
```python=
i = ['amos', "taipei", 44] #list裡面可以放置不同的資料型態
print(i) #i是一個list,把i列印出來在畫面上面看看是什麼?
print(i[2]) #透過[]取得i裡面的值,然後再列印出來會得到 44
i[1] = '台北'
print(i) # ['amos', "台北", 44]
```
* list其他操作
```python=
i = [1, 100, 10, 5]
print(i[1])
i.append(0.2) # 追加資料
print(i)
i.insert(2, 50) # 從第2筆插入50
print(i) # ???
i.remove(1) # 移除list內第一個符合該內容的資料!
print(i)
i.index(1) # 取得1在list中的索引值(第幾位)
print(i)
i.pop(i) # 取出,採先進後出法
print(i)
i.sort() # 由小到大排序
print(i)
i.reverse() # 由大到小排序
print(i)
print( len(i) ) # 求list筆數
print( max(i) ) # 求list中最大值
print( min(i) ) # 求list中最小值
print( sum(i) ) # 將總list內的數值
i.clear() # 清除全部內容
print(i)
```
### tuple
* tuple的建立是使用()與逗號","
```python=
i = (1, "taipei", 2)
print(i)
```
### set
```python=
i = {1, "taipei", 5}
print(i)
print("taipei" in i) # True
i.add("高雄")
print(i) # {1, 'taipei', 5, '高雄'}
```
### dict
```python=
j = {
"id": "A1122",
"name": "Amos Tsai",
"year": 5
}
j["id"] = "AAAA"
print(j["id"]) #"AAAA"
member = {
"number": "1020501",
"name": "小傑",
"age": 32,
"sex": "M",
"interest": [
"網頁設計",
"撰寫文章"
]
}
member['interest'] # ["網頁設計", "撰寫文章"]
member['interest'][0] # 網頁設計
```
```python=
school = [
{ "id": "A1122", "name": "Amos Tsai", "year": 5 },
{ "id": "A1123", "name": "frank", "year": 3}
]
a = ["amos", "frank"]
print(school[1]['name']) #frank
```
```python=
school = { "id": "A1122", "name": "Amos Tsai", "year": 5 }
school = list(school.values())
print(school) #['A1122', 'Amos Tsai', 5]
print(type(school)) #<class 'list'>
a = [123, 555, "abc"]
print(a) #[123, 555, 'abc']
print(type(a)) #<class 'list'>
a = tuple(a) #沒東西
print(a) #(123, 555, 'abc')
print(type(a)) #<class 'tuple'>
```
### 大型容器
> Only an example
```python=
#大型資料集
BigContent = {
"1":
"Function": [
"網頁設計",
"資料庫串接"
],
"2":
"Function": [
"專案管理",
"文件撰寫"
]
"3":
"Function": [
"法規制定",
"行政流程"
],
...
}
```
}
## 程式結構 (流程控制)
### if
```python=
sleep = True
if sleep: # 末端為分號 :
print("End class !")
```
### if, elif, else
```python=
iphone15 = "Blue"
if iphone15 == "Blue":
print("Buy for myself")
elif iphone15 == "Pink":
print("Buy for mom")
else
print("Don't buy")
```
### while
```python=
count = 1
while count <= 5
print(count)
count += 1
#以下為顯示結果
1
2
3
4
5
```
### break
```python=
count = 1
while count <= 5
print(count)
# >= 3的時候強制跳離,下面就不執行+1的動作了,直接結束 while 迴圈
if count >= 3
break
count += 1
#以下為顯示結果
1
2
3
#程式結束
```
### continue
```python=
count = 1
while count <= 5
print(count)
# >= 3的時候會跳過下方+1的動作
if count >= 3
continue
# count一直無法+1,此while會造成無窮迴圈,成是會一直卡在這邊無法繼續往下執行
count += 1
#以下為顯示結果
1
2
3
#但是python程式會一直執行,無法結束。
```
### for 與 in 迭代
* 在特定範圍內迭代內容,自己覺得使用 for 比較安全
```python=
word = "hello!"
for letter in word
print(letter)
# 結果
h
e
l
l
o
!
# while 也一樣可以達到同樣的效果
offset = 0 #給定位置指標
while offest < len(word)
print(word[offset])
offset += 1
```
# P.99
## 函式 Function
## 模組
## 物件
## 套件
# Part 2
## 爬蟲套件介紹
## 爬蟲許願池
## 來寫爬蟲
* 商工登記公示資料查詢服務網站查詢王永慶的爬蟲範例
```python=
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
import time
import random
#商工登記公示資料查詢服務
url = 'https://findbiz.nat.gov.tw/fts/query/QueryBar/queryInit.do'
#查詢人名
SearchName = '王永慶'
#SearchName = '張忠謀'
# list轉換Dictionary - 目前沒用到
def convert2Dict(lst):
res_dict = {}
for i in range(0, len(lst), 3): #3個為一組
res_dict[lst[i]] = lst[i + 1]
return res_dict
# 裝睡
def PretentSleep(s, e):
r = random.randint(s, e)
print('裝睡' + r.__str__() + '秒')
browser.implicitly_wait(r)
# 以下為 main 開始
browser = webdriver.Chrome()
#開網頁
browser.get(url)
print('網頁內容')
print(browser.page_source)
#找到輸入框
QueryName = browser.find_element(By.NAME, 'qryCond')
QueryName.send_keys(SearchName)
#找到radio的按鈕
QueryType = browser.find_element(By.ID, 'infoName')
QueryType.click()
#為了不要讓網站發現爬蟲
PretentSleep(1, 3)
#找到查詢按鈕
queryBtn = browser.find_element(By.ID, 'qryBtn')
queryBtn.click()
#等待 wait 為了不要讓網站發現爬蟲
PretentSleep(3, 5)
# #切換為表格型式
# viewType = browser.find_element(By.ID, 'viewTable')
# viewType.click()
TotDataRowCount=0
currentPage=1
maxPage=1
try:
#找到總頁數
TotDataRowCount = browser.find_element(By.NAME, 'pagingModel.totalCount').get_attribute('value')
print('資料總筆數 : ' + TotDataRowCount)
currentPage = browser.find_element(By.NAME, 'pagingModel.currentPage').get_attribute('value')
print('目前分頁 : ' + currentPage)
maxPage = browser.find_element(By.NAME, 'pagingModel.totalPage').get_attribute('value')
print('最大分頁 : ' + maxPage)
except:
print("沒有其他分頁")
#設計分頁點選
#抓取公司資訊
CompanyInfos = browser.find_element(By.ID, 'vParagraph')
print(type(CompanyInfos))
splitinfo = CompanyInfos.text.split('\n') # it is a list
res_dict = {}
for i in range(0, len(splitinfo), 3):
#這邊僅用逗號區隔資料為list,後面要固定欄位index去抓取固定的值
detailInfo = splitinfo[i+1].split(',')
for k in range(0, len(detailInfo)):
detailInfo[k] = detailInfo[k].replace(' ', '')
#加入到 dictionary 裡面,這邊就是完整爬取的資料了
res_dict[splitinfo[i]] = detailInfo
#彙整不同頁數的資料集
browser.quit()
#資料集寫入當地 csv 檔
```
## 請 ChatGPT 幫忙寫 Python
### Prompt
* 請寫一段python function,function要可以讀取一個Excel檔案,這個Excel檔案內共有兩個頁籤都需要被讀取,第一個頁籤內容有5個欄位與10個列,第二個頁籤內容有2個欄位與20個列,分別讀取後,將讀取後的內容放在不同的 Dictionary 中並回傳。
### ChatGPT 的回答
* 先安裝套件

* 開始幫你寫 python 程式

* ChatGPT實際產出的程式碼
```python=
import pandas as pd
def read_excel_to_dict(file_path):
# 創建兩個字典,用於存放兩個頁籤的內容
sheet1_data = {}
sheet2_data = {}
# 讀取 Excel 檔案
xls = pd.ExcelFile(file_path)
# 讀取第一個頁籤的內容
# 頁籤名稱要與檔案內容相同
sheet1_df = pd.read_excel(xls, sheet_name='第一個頁籤')
# 將第一個頁籤的內容轉換為字典
for column in sheet1_df.columns:
sheet1_data[column] = sheet1_df[column].tolist()
# 讀取第二個頁籤的內容
# 頁籤名稱要與檔案內容相同
sheet2_df = pd.read_excel(xls, sheet_name='第二個頁籤')
# 將第二個頁籤的內容轉換為字典
for column in sheet2_df.columns:
sheet2_data[column] = sheet2_df[column].tolist()
# 回傳兩個字典
return {'第一個頁籤': sheet1_data, '第二個頁籤': sheet2_data}
# 使用示例
file_path = '你的Excel檔案.xlsx' #這邊要改成自己的檔案路徑
result = read_excel_to_dict(file_path)
print(result)
```
* 執行結果
