# 爬蟲資料匯入Excel ###### tags: `工讀` [toc] :::info ### 目標 成功爬取 [此網站](https:[//](https://university-tw.ldkrsi.men/caac/)) 的以下資訊並匯入excel 1. 學校代碼 2. 學校名稱 3. 系所代號 4. 系所名稱 ::: 遇到的困難 ## 爬蟲 我一開始選擇用class爬學校,也成功了。但後來考慮到還要爬科系,所以改用tag爬。 而[這個網頁](https://university-tw.ldkrsi.men/caac/)基本上有**兩個select**,也就是**兩個選單**。 步驟 : 1. 用tag找出'select' `driver.find_element(By.TAG_NAME ,'select')` > 這邊find_element沒加s是因為此時需要的是第一個選單(各學校),不會用到第二個選單(各系所)。而find_element只會抓第一筆,符合要求。 2. 每個option會有該校的value和inner html(也就是我們在網站上看到的文字)。所以接下來要用選項option抓全部學校的value, - 這邊**每所學校的option value不一定等於我們在網站上看到的該學校代碼(inner html)**。 > ex:校代碼是109的普大option value=109,而校代碼是109的科大option value=j109 > 我一開始以為學校的校代碼跟option value數字是一樣的,畢竟primary key有兩個很不合理。 後來才發現有些普大和科大的校代碼一樣,但他們的option value不可能一樣。(畢竟option value是獨一無二的)。 我原本以為他的value是連續的(ex:0~200),這樣的話就很簡單,只需要一個一個加就好,殊不知到頭來需要去抓一堆option value。這邊花了很多時間,這部分設計的很奇怪。 3. 該怎麼抓所有value? (這邊的value不是指校代碼喔,校代碼只是inner html) - 把所有option找出來(裡面會有各校value、校代碼、校名) `search_input = driver.find_elements(By.XPATH, "//option")` - 把選單內該一個學校option 抓下來`.get_attribute("value")` 4. 知道所有學校的value後,就可以用value來抓系的資料 - 用Select(點選的功能) 點選第一個選單(有全部校名的那個選單) `search_input = Select(driver.find_element(By.CSS_SELECTOR, "select"))` (這個套件提供的點選功能很讚) > 還有查到select_by_visible_text(應該是指inner html)等功能。 - 用value去模擬人依序點選選單內的學校(照option value依序由上往下點選) `.select_by_value(value)` - 接著要點選第二個選單去抓系,要考慮到在選單點選不同學校後,科系也會跟著改變(不同學校有的科系不同)。 - find_elements會抓到兩個選單,我們這邊要使用得是第二個選單(有該校所有科系)。 `search_input = driver.find_elements(By.XPATH, "//select") ` > search_input 現在有{所有學校}和{該校對應的所有科系}這兩個選單。 - 用.text抓到第二個選單所有option的inner html(系代碼和系名),再用for迴圈把該校的全部科系資料放進final這個list `final=search_input[1].text.split("\n")` ## 匯入資料到excel 1. 創一個字典叫做dict,再添加資料進去 {key=各學校代碼+校名,value=該校各系代碼+系名} `dict[total_school_name[index]] = final ` 2. 輸入第一列標題 ```python= s1.cell(1,1).value="學校代碼" s1.cell(1,2).value="學校名稱" s1.cell(1,3).value="校系代碼" s1.cell(1,4).value="校系名稱" ``` 3. 然後依序把資料匯入 ```python= school_num=1 #算到第幾所學校 row=2 #一開始要從第二列開始寫,之後再往下寫 for key, value in dict.items(): #各學校詳細資料 (key) for i in value: #該校所有科系資料(value) s1.cell(row,1).value=(total_school_name[school_num])[1:4] s1.cell(row,2).value=(total_school_name[school_num])[6:] s1.cell(row,3).value=i[1:7] #寫入系代碼 s1.cell(row,4).value=i[9:] #寫入校名 row+=1 school_num+=1 ``` --- ## 學習到的功能 > 因為我從來沒學過css和js,也完全沒碰過網頁,所以花很久時間在查資料,查了幾天沒進展的話就會跟同學求助。 > 下面是一些這次學習過程中,我覺得蠻好用的技巧,想紀錄下來。 - F12 -> 主控台 -> 輸入 `document.getElementsByTagName.('要搜尋的tag')` -> ![](https://i.imgur.com/0RQjspl.png) - [0]代表第一個選單(index[0]) ![](https://i.imgur.com/0KszqAH.png) - `document.getElementsByTagName('select')[0][1]`的[1]代表選單的第2項(因為其index[1]) ![](https://i.imgur.com/Hn1d57V.png) --- ### Excel文件在openpyxl的名詞代號 - `workbook`(活頁簿):也就是一個excel檔案 - `worksheet`(工作表):一個excel可以有很多個工作表,目前正在觀看或處理的工作表又稱作「活動中的工作表(active sheet)」 - 欄(column):工作表中的直欄,以A、B、C…代表 - 行(row):工作表中的橫列,以1、2、3…代表 - 儲存格(cell):工作表中的每一個都是一個資料儲存格,每一格稱為`cell(row, col)`。 ### 建立Excel檔案 - 前置寫入 ```python= import openpyxl import os ``` - 切換到電腦指定路徑 ```python= os.chdir(r"C:\Users\annnn\crawler") # os.chdir 是 python ``` > 要記得程式正在操作的檔案是我們填入路徑下的那個檔案,儘管excel檔案名稱一樣,在不同路徑下開啟會看起來有所不同。 **簡單來說就是,要從對的路徑開excel檔案,才能看到剛才編輯的結果。** - 建立新Excel檔案(Workbook) ```python= wb = openpyxl.Workbook() ``` - 開啟舊Excel檔案 ```python= wb = openpyxl.load_workbook('test1.xlsx') ``` - 儲存檔案 `wb.save('test1.xlsx')` > 以上指令做完後,達成在指定路徑下(C:\Users\annnn\crawler)存了新檔案('test1.xlsx') ### 操作Excel工作表 > - 開啟 Excel 活頁簿後,可以使用 active 屬性取得目前使用的工作表 ( 開啟 Excel 活頁簿時第一個顯示的工作表 ) > - 使用字典取值的方法讀取指定名稱的工作表 --- 可以加強的: 下關鍵字的能力/把小功能分開練習