項(xiàng)目需要一個爬蟲,正好朋友有一個閑置樹莓派3b+拿來用。事實(shí)再一次證明,任何看起來很簡單的事情其實(shí)都很復(fù)雜。而那些可能會發(fā)生的錯誤則一定會發(fā)生 (`⌒′メ)
環(huán)境:
- Raspberry Pi 3b+
- Raspbian 操作系統(tǒng) (基于 Debian stretch9)
顯示問題
無信號
首當(dāng)其沖的是接好屏幕卻無信號,光是這個問題就折騰了一小時。根據(jù)經(jīng)驗(yàn),這種詭異的問題其原因往往非常簡單,這次也不例外。因?yàn)橹挥幸粔K顯示器,所以要樹莓派與電腦輪流使用。不巧,這東西不支持 HDMI 熱插拔,開機(jī)時沒檢測到 HDMI 之后就默認(rèn)為模擬輸出了。找到問題對癥下藥就好啦,編輯系統(tǒng) sd 卡根目錄下的 Config 文件:
# 找到這行配置,刪除前面的#取消注釋就好啦。
# 這會強(qiáng)制使用 HDMI 輸出無論是否連接了顯示器。
hdmi_force_hotplug=1
分辨率無法調(diào)節(jié)

默認(rèn)分辨率很低,以至于設(shè)置窗口都顯示不全。無論是直接編輯配置文件還是使用 UI 修改均無效。又是一個多小時的折騰,了解到它會自適應(yīng)顯示屏來調(diào)節(jié)分辨率忽略用戶設(shè)置。同時猜測是不支持熱插拔的緣故,導(dǎo)致無法正確識別顯示器分辨率。同樣繼續(xù)編輯配置文件:
# 加入下面這行忽略自動調(diào)節(jié)
hdmi_ignore_edid=0xa5000080
hdmi_group=1 # 1是CEA多用于電視,2是DMT多用于顯示器
hdmi_mode=52 # 根據(jù)顯示器分辨率調(diào)節(jié),具體代碼含義網(wǎng)上有很多資料。
# 比如: http://shumeipai.nxez.com/2013/08/31/custom-display-resolution-raspberry-pie.html
這下顯示問題終于搞定了。
切換源
眾所周知的,先把源 切換成國內(nèi)來節(jié)約時間,這里使用清華開源鏡像站,直接根據(jù)幫助文檔操作就好。
修改 /etc/apt/sources.list,注釋掉原來的所有內(nèi)容,用下面內(nèi)容取代:
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ stretch main non-free contrib
deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ stretch main non-free contrib
然后修改 /etc/apt/sources.list.d/raspi.list,用下面內(nèi)容取代:
deb http://mirrors.tuna.tsinghua.edu.cn/raspberrypi/ stretch main
最后執(zhí)行 sudo apt-get update 更新下軟件源列表就好啦。
Docker
為了快速配置運(yùn)行環(huán)境,首先想到的方案就是 Docker。根據(jù)官方文檔進(jìn)行安裝。
最后發(fā)現(xiàn) x86 打包的鏡像是不能在 ARM 上使用的,交叉編譯太太太折騰,遂放棄 docker 方案。
警告 根據(jù) Docker 文檔,Raspbian 不能使用 apt 直接安裝,而應(yīng)該手動進(jìn)行,推薦使用 docker 提供的便攜腳本。
執(zhí)行下面命令下載便攜腳本并開始安裝:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun # 使用阿里云鏡像加速安裝
樹莓派默認(rèn)使用 pi 用戶登錄,我們需要將它添加到 docker 用戶組,這樣每次管理容器的時候不需要都加 sudo 了:
sudo usermod -aG docker pi # 注意需要注銷重新登錄來生效
最后設(shè)置下開機(jī)自動啟動:
sudo systemctl enable docker
這樣 docker 環(huán)境就裝好了。
升級 Python
Docker 不行就回到原生 Python 環(huán)境吧。默認(rèn)安裝的還是 2.x,把它升級成 3.6。首先更新軟件包并安裝所需依賴:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential libsqlite3-dev sqlite3 bzip2 libbz2-dev
下載所需版本 Python 并解壓:
wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz
tar -zxvf Python-3.6.8.tgz
編譯安裝一氣呵成,速度有點(diǎn)慢可以去喝杯奶茶:
cd Python-3.6.8
sudo ./configure & sudo make & sudo make install
完成后執(zhí)行 python3 --version 測試下是不是裝好了。但是 python 還是調(diào)用 2.x 的版本。執(zhí)行 which python 定位一下,發(fā)現(xiàn)位于 /usr/bin/python。那就好辦了,刪除然后重新創(chuàng)建一個軟鏈接:
sudo rm /usr/bin/python
sudo ln -s /usr/bin/python3 /usr/bin/python
# 執(zhí)行 `which python3` 可獲得 python3 的位置
這樣 Python 就搞定了。
令人崩潰的 pip
用過 py 的肯定知道 pip 的重要性,這次偏偏就不好使了。執(zhí)行 pip 直接報(bào)錯 ImportError: cannot import name 'main'。最終從網(wǎng)上找了一個看起來不靠譜的方案,但實(shí)際很有效果。修改 sudo vim /user/bin/pip,將原先的代碼改成下面這樣的:
from pip import __main__
if __name__ == '__main__':
sys.exit(__main__._main())
如此一來 pip 總算可以跑起來了。接著是另一個老生常談的問題,找不到 ssl 模塊,導(dǎo)致無法連接 https 導(dǎo)致 pip 無法安裝或更新。網(wǎng)上常見的編譯加 --with-ssl 并沒有什么幫助。
最后又是一個看起來不是很靠譜但真的很管用的方法:
首先確保所需的依賴已經(jīng)安裝了:
sudo apt-get install openssl
sudo apt-get install libssl-dev
在進(jìn)行過一次編譯之后,編輯 py 解壓的安裝包目錄下 ./Modules/Steup 文件,搜索 SSL 關(guān)鍵字,找到下面內(nèi)容并取消代碼的注釋(共4行):
# Socket module helper for socket(2)
_socket socketmodule.c # ←取消這行注釋
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
#SSL=/usr/local/ssl
_ssl _ssl.c \ # ←取消這行注釋
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ # ←取消這行注釋
-L$(SSL)/lib -lssl -lcrypto # ←取消這行注釋
然后重新編譯安裝 sudo make & sudo make install 即可。
Screen
個人習(xí)慣,到手 linux 必備 screen,樹莓派也不例外。screen 可以幫助管理遠(yuǎn)程會話,即使斷開連接也不會終止正在執(zhí)行的任務(wù)。重新連接可以快速恢復(fù)之前的會話。
安裝 Screen 非常簡單,直接 sudo apt-get install screen 就可以了。
Screen 的基礎(chǔ)使用也很簡單。執(zhí)行 screen 可以新建一個會話,這會打開一個全屏 shell 窗口程序,在其中可以執(zhí)行任意操作,就像 ssh 窗口那樣。
Screen 的基本單位是窗口。創(chuàng)建會話時會自動創(chuàng)建一個窗口,一個會話可以有多個窗口。若關(guān)閉/斷開的是當(dāng)前會話的最后一個窗口,則自動關(guān)閉/斷開會話。
Screen 的命令用 Ctrl+a 激活。因?yàn)槟J(rèn)按鍵信息會發(fā)往 shell 窗口,所以需要一個組合鍵來通知 Screen 下面是命令操作。神奇的地方來了,使用 C-a d 可以暫時斷開當(dāng)前窗口,并將其留在后臺,其任務(wù)也會繼續(xù)執(zhí)行。此時可以放心地?cái)嚅_ ssh 連接。重新連接后使用 screen -r 可以快速恢復(fù)之前斷開的會話(如果有且只有一個會話),這樣執(zhí)行一個長期任務(wù)就不用擔(dān)心斷掉了。
如果有多個會話,使用 screen -ls 查看會話列表,前面都是數(shù)字就是 id,使用 screen -r [id] 可以恢復(fù)會話。也可以使用 screen -S [name] 創(chuàng)建一個自定義名稱的會話,這樣可以使用 screen -r [name] 來快速恢復(fù)。
下面是在 Screen 窗口中的常用的操作:
| 操作 | 功能 |
|---|---|
| C-a ? | 幫助 |
| C-a d | 暫時斷開當(dāng)前窗口 |
| C-a k | 關(guān)閉當(dāng)前窗口 |
| C-a A(注意大寫) | 重命名當(dāng)前窗口 |
| C-a w | 顯示窗口列表 |
| C-a c | 創(chuàng)建并且到一個新窗口 |
| C-a C-a | 切換到之前窗口,可在兩個窗口間快速切換 |
| C-a n/p/[0,9] | 切換到下一個/上一個/指定的窗口 |
| C-a a | 發(fā)送C-a到窗口,有點(diǎn)轉(zhuǎn)義字符的感覺 |
更多的 Screen 教程推薦這個。