昨天搞定忙了三天的市立圖書館爬蟲程式, 因為打算要部署在樹莓派, 想說先到樹莓派上測試一下 Firfox/Chronium 的 Web Driver 是否管用, 雖然今年三月曾在鄉下的 Pi 3 上安裝測試過 Chronium 的 Web Driver 確認可用, 但這次在高雄這塊 Pi 上卻不行, 甚至連線回去鄉下的 Pi 3 居然無法載入 Web Driver, 明明測試 OK 後甚麼都沒動, 居然兩個月之後 GG 了. 從昨晚到今天早上不斷尋找解決辦法都徒勞無功, 最後決定放棄. 參考 :
轉頭想起已經兩三個月沒摸的 Mapleboard, 它的效能比 Pi 3 好太多 (64 位元 CPU + 4GB DRAM), 而且在 Ubuntu 22.04 上直接安裝最新的 Selenium 4 跟 Windows 一樣, 或許直接用 Firefox 就可以不用改程式直接跑圖書館爬蟲程式了. 但過程也沒想像中順利, 還是遇到 Firefox Web Driver (gecko) 版本與路徑問題, 所幸有在網路上找到解決方案順利完成 Firefox 驅動程式載入問題, 過程紀錄如下 :
1. 安裝 Selenium :
這部分沒有問題, 安裝到最新版的 Selenium v4.21.0 :
tony1966@LX2438:~$ pip3 install selenium
Defaulting to user installation because normal site-packages is not writeable
Collecting selenium
Downloading selenium-4.21.0-py3-none-any.whl (9.5 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 9.5/9.5 MB 5.0 MB/s eta 0:00:00
Collecting certifi>=2021.10.8
Downloading certifi-2024.2.2-py3-none-any.whl (163 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 163.8/163.8 KB 5.5 MB/s eta 0:00:00
Requirement already satisfied: urllib3[socks]<3,>=1.26 in /usr/lib/python3/dist-packages (from selenium) (1.26.5)
Collecting typing_extensions>=4.9.0
Downloading typing_extensions-4.12.0-py3-none-any.whl (37 kB)
Collecting trio~=0.17
Downloading trio-0.25.1-py3-none-any.whl (467 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 467.7/467.7 KB 5.2 MB/s eta 0:00:00
Collecting trio-websocket~=0.9
Downloading trio_websocket-0.11.1-py3-none-any.whl (17 kB)
Collecting attrs>=23.2.0
Downloading attrs-23.2.0-py3-none-any.whl (60 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 60.8/60.8 KB 3.5 MB/s eta 0:00:00
Requirement already satisfied: idna in /usr/lib/python3/dist-packages (from trio~=0.17->selenium) (3.3)
Collecting sortedcontainers
Downloading sortedcontainers-2.4.0-py2.py3-none-any.whl (29 kB)
Collecting outcome
Downloading outcome-1.3.0.post0-py2.py3-none-any.whl (10 kB)
Collecting sniffio>=1.3.0
Downloading sniffio-1.3.1-py3-none-any.whl (10 kB)
Collecting exceptiongroup
Downloading exceptiongroup-1.2.1-py3-none-any.whl (16 kB)
Collecting wsproto>=0.14
Downloading wsproto-1.2.0-py3-none-any.whl (24 kB)
Collecting PySocks!=1.5.7,<2.0,>=1.5.6
Downloading PySocks-1.7.1-py3-none-any.whl (16 kB)
Collecting h11<1,>=0.9.0
Downloading h11-0.14.0-py3-none-any.whl (58 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.3/58.3 KB 2.8 MB/s eta 0:00:00
Installing collected packages: sortedcontainers, typing_extensions, sniffio, PySocks, h11, exceptiongroup, certifi, attrs, wsproto, outcome, trio, trio-websocket, selenium
Successfully installed PySocks-1.7.1 attrs-23.2.0 certifi-2024.2.2 exceptiongroup-1.2.1 h11-0.14.0 outcome-1.3.0.post0 selenium-4.21.0 sniffio-1.3.1 sortedcontainers-2.4.0 trio-0.25.1 trio-websocket-0.11.1 typing_extensions-4.12.0 wsproto-1.2.0
檢查版本 :
tony1966@LX2438:~$ python3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import selenium
>>> selenium.__version__
'4.21.0'
2. 下載 Firefox Web Driver : (此步驟似乎是多餘的)
我原先參考之前的筆記 :
與下面這篇教學 :
開啟 Mapleboard 的 Firefox 連線 Firefox 驅動程式下載網址 :
往下拉到 "Assets" 這區塊, 要選擇最上面 linux-aarch-64 的那個下載 :
我第一次是下載 linux-64 那個, 但呼叫 webdriver() 時卻出現下面兩個錯誤訊息 :
"selenium.common.exceptions.WebDriverException: Message: Unsupported platform/architecture combination: linux/aarch64"
"OSError: [Errno 8] Exec format error: '/usr/local/bin/geckodriver'"
經搜尋才知道這錯誤是因為安裝了錯誤的驅動程式版本所致, Mapleboard 的 Linux 是 aarch 版本的才對, 改下載 linux-aarch-64 的那個才決此問題, 參考 :
"You have most probably installed a version of geckodriver that is meant for a different OS/platform! get the correct version from https://github.com/mozilla/geckodriver/releases and replace the one you have"
這過程中也順便學到一個查詢系統與 CPU 是 32/64 位元的 Linux 指令 :
getconf LONG_BIT
tony1966@LX2438:~$ getconf LONG_BIT
64
參考 :
驅動程式下載後直接在 Desktop 操作解壓縮, 或在終端機使用 tar -xvf 指令將 .gz 檔解開, 得到一個 geckodriver 檔案, 然後將它移動到 /usr/local/bin 底下, 並且用 chmod 指令將其變更為可執行檔 :
tony1966@LX2438:~/python$ sudo mv geckodriver /usr/local/bin/
[sudo] tony1966 的密碼:
tony1966@LX2438:~/python$ cd /usr/local/bin
tony1966@LX2438:/usr/local/bin$ sudo chmod +x geckodriver
結果還是無效, 出現如下錯誤 :
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Process unexpectedly closed with status 1
3. 使用 Firefox 內建的 geckodriver 驅動程式 :
最後找到這篇 :
原來 Mapleboard 上安裝的 Firefox 是 snap 版 (Ubuntu 22.04 預載), 已經內建了 Firefox 的驅動程式 geckodriver, 只要用 ln 指令連結它即可, 先用 whereis 指令尋找 firefox.geckodriver 路徑 :
tony1966@LX2438:~/python$ whereis firefox.geckodriver
firefox.geckodriver: /snap/bin/firefox.geckodriver '
然後用 ln 將其連結至 geckodriver :
tony1966@LX2438:~/python$ ln -s /snap/bin/firefox.geckodriver geckodriver
這樣就會在目前工作目錄 python 下建立一個 geckodriver 連結 :
但必須用 Selenium 4 新的連結驅動程式的作法, 使用 Service 類別來建立 Service 物件 :
>>> from selenium import webdriver
>>> from selenium.webdriver.chrome.service import Service
>>> driverpath = './geckodriver' # 指定驅動程式連結的路徑
>>> firefox_service = Service(driverpath)
>>> browser=webdriver.Firefox(service=firefox_service) # 傳入 Service 物件載入驅動程式
>>> browser.get('https://tw.yahoo.com')
結果如下 :
終於搞定了!
順便記一下插曲 : 雖然上面呼叫 Firefox() 不再馬上跳出錯誤, 看起來正在啟動 Firefox 時, 卻突然出現 "Profile missing" 視窗 :
我參考下面這篇官方教學 :
在 Mapleboard 手動開啟 Firefox, 然後在網址列輸入 about:profiles 按 Enter 就會跳出下面視窗 :
甚麼都不用動, 使用 default profile 開啟 Firefox, 直接按右下角的 Start Firefox 鈕, 再次執行 webdriver.Firefox() 就不會再抱怨找不到 profile 而順利開啟瀏覽器.
2024-05-25 補充 :
我回到 Windows 用上面的 Service 物件發現會出現錯誤, 似乎 Windows 上直接呼叫 webdriver.Firefox() 即可, 如要無頭模式就傳入 options=options.
另外, 在下面這篇文章中提到使用 Phantom.js 可以避開 WebDriver 問題 :
有空可以來測試看看.
沒有留言 :
張貼留言