前往
大廳
主題

[Python] 爬蟲程式練習2

Kmyth | 2023-11-01 01:23:51 | 巴幣 0 | 人氣 200

通勤滑手機,看到有趣的心理測驗,就丟到DC群
意外滿多人回覆,就想說整理一張全體的圖出來。

不過問題是,網站並沒有給出所有測驗結果的圖片,
只能自己去做試驗蒐集結果。
本來想說應該試個幾次應該可以試出來,
不知道是結果分配不均,還是運氣不好,總之就是缺了四種。
已經耗掉一天,無奈之下,還是只能搬出爬蟲來搞。

總之,最後有把圖弄出來:



動態爬蟲

主要函式庫:selenium
說明:
前一次只需要分析靜態頁面,找到位置,抓到對應物件的資料即可。
這次不同,需要回答12個問題,點擊後讓頁面跳轉,是動態的爬蟲。
因此需要webdriver─透過程式碼指令,模擬實際網頁的各項操作。
每個瀏覽器的架構都不同,也因此各自用到的webdriver也不同。
這邊我用到的是chrome,就是去載chromedriver。

流程:
driver = webdriver.Chrome() #開啟chromedriver
driver.get(url)  #連上特定網頁
driver.find_element(By.CLASS_NAME, 'XXX').click()  #找到物件,並執行點擊

然而一開始就卡關,馬上就頭大了起來。
最討厭搞這種環境設置的各種問題。

難關1:版本問題
即使是同一個瀏覽器,也會因為版本不同,對應的webdriver也不同。
解法:(都弄到最新最方便)
把瀏覽器更新到最新,然後也抓最新版的chromedriver。

難關2:路徑問題
不知道為何,明明把chromedriver跟程式碼的檔案放在同一個資料夾,
就是抓不到chromedriver,一直跟我講沒有driver用。
想了一下,可能是抓底層設置,也就是python的位置,而找不到chromedriver。
解法(直接指定路徑)
加了一行,指定路徑,並把參數丟到driver裡
s = Service(r"C:\......\chromedriver.exe")
driver = webdriver.Chrome(service=s)

難關3:延遲問題
因為頁面跳轉時,畫面讀取的時間差,程式往下跑的時候,可能畫面資料還沒讀完,
結果就導致物件抓不到,引發錯誤,程式停擺
解法(設置延遲)
利用休眠,讓程式碼等網頁讀取完後再跑。
time.sleep(1)
精進
然而這個時間不好抓,每次執行必須停等的時間會依據網路讀取速度而定。
等於是設定的越短,觸發錯誤的機率越大;
但設定太長,又會導致整體執行時間過長。
可能寫成錯誤發生的例外,再延長停等時間,重複嘗試,更好。

圖片儲存

因為要把測驗的結果記錄下來,
而結果頁面是以圖片呈現,等於要把圖抓下來。

方法1:GUI操作
函式庫:pyautogui
程式碼:
action = ActionChains(driver).move_to_element(result)  # 移動到該元素
action.context_click(result)  # 右鍵點選該元素
action.perform() # 執行
pyautogui.typewrite(['v']) # 敲擊V進行儲存
#單擊圖片另存之後等1s敲確認
time.sleep(1)
pyautogui.typewrite(['enter'])

方法2:Image
函式庫:PIL
程式碼:
img_content = requests.get('http://...')
img = Image.open(io.BytesIO(img_content)).save(filename)
說明:
用於可直接取得圖片網址的情形。
且不將圖片儲存,也可以直接對圖片內容進行後續其他操作。(去除.save段)

難關4:http之外的圖片"網址"
然而,網路圖片居然還有網址之外的表示方式,好死不好就遇到了。
大概是這種形式:"data:image/png;base64,...",也就是所謂的data URI
解法:(資料型態轉換)
多寫兩行,將資料以byte的形式儲存,再用base64去解碼。
b = bytes(img_src, 'utf-8')
img_content = base64.b64decode(b)

圖轉文字

然而,做到一半覺得好像沒必要存成圖片,浪費空間。
因為重點是圖片中顯示結果種類的關鍵幾個字而已。
又想到已經有圖轉文字的模組可以用。

主要函式庫:pytesseract
說明:
webdriver一樣,直接指定路徑。
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

難關5缺中文模組
不給予任何參數的情況下,會以英文為預設來汲取文字。
而中文必須於安裝時,有選取才會安裝額外的模組。
解法:(補上模組)
最快就整個重裝,要勾選到中文模組。
並且於使用時,指定用繁體中文來解析。
text = pytesseract.image_to_string(img, lang='chi_tra')

資料輸出

主要函式庫:pandas
程式碼:
df = pd.DataFrame(data=article_info_row_data, columns=columns)
df.to_csv('./test_pandas.csv', index=0, encoding='big5')
說明:
把資料裝一裝,然後用輸出成CSV檔。

難關6:亂碼
解法:(更改編碼)
就是試錯,本來以為應該是用網頁內容的UTF-8格式,
但既然是中文,就big5丟進去試試,然後就正常顯示了。

實際執行

難關7:Anaconda 閃退無法開啟
因為前面各種碰壁,寫了一個段落,想說隔天再來跑執行。
結果過了一晚Anaconda 就爆炸,莫名其妙開不起來。
解法:(重灌)
萬金油,就是全部重來,然後就又可以執行了。
之後發現,好像是硬碟的某個部分壞掉,剛好是Anaconda 的資料夾位置。

難關8:執行時間過長
也就是前面提的休眠時間的問題。
12個問題,總共4096種組合,
相較於機械學習動不動就5、6位數組的訓練資料,感覺很少。
但實際上,休眠時間設定的關係,一組也要跑個30秒左右,
也就是4096組需要2048分鐘,也就是34小時多,超過一天。
解法:(無)
其實也不是沒有,就前面講的,可能弄成例外情形去處理,盡量最小化休眠時間。
精進
另外,應該階段性輸出資料,不然跑到一半停電甚麼的...時間就白等了。
還好一次就順順的成功。

難關9資料錯誤
最後出來的資料只有三種測驗結果,顯然是有某個環節出錯,但是無法得知是甚麼問題。
可能是對於time.sleep() 理解上的錯誤,譬如程式碼實際是有先往下跑,導致接連後續的迴圈都是同樣的值,而使CSV輸出的值有誤。
解法:(切分執行區塊)
結果還是半手動的方式,一小塊一小塊去執行,然後也老老實實的存圖檔,看有沒有問題
很幸運的抓出漏掉的四種結果就不跑了。
原本是想測出4096種組合的結果,看16種性格的分布情形。
可是在做的時候,發現名稱不同好像也會導致結果受到影響...
等於是有第13個變項,詳細又要做更多試驗,
因為只是個支線任務,所以就作罷了。

創作回應

相關創作

更多創作