# Part 1 ## 安裝 ### [Python官方連結](https://www.python.org/) * 點選 download 下載最新版本,目前是3.11.5版,下載完畢後直接安裝。 ![python.org](https://hackmd.io/_uploads/H1x8EJCRn.png) ### [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) ![](https://hackmd.io/_uploads/HyU8HJR0n.png) ### 安裝後確認 * 開啟 cmd,輸入下方指令(小寫v),可進入 python "測試功能模式"。 * 若要結束此模式,可輸入 Ctrl+Z 即可跳回原來的模式。 ```python= python -v ``` * 開啟 cmd,輸入下方指令(大寫V),可查看安裝版本。 ```python= python -V ``` ![](https://hackmd.io/_uploads/H18wv1RC2.png) :::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 的回答 * 先安裝套件 ![安裝套件](https://hackmd.io/_uploads/SJ-vHgdWp.png) * 開始幫你寫 python 程式 ![寫程式](https://hackmd.io/_uploads/HyAdHedWT.png) * 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) ``` * 執行結果 ![執行結果](https://hackmd.io/_uploads/HyBKnluba.png)