2018年5月23日 星期三

利用網頁控制樹莓派(Raspberry Pi)運作

這算是很多人應用過的項目了
最近重碰Python也想到之前看過用Python的RPI.GPIO用網頁控制
就順便試著實作看看了

其實也很簡單,先把Python程式寫出來,程式碼如下:
#!/usr/bin/python3
"""上面這行不是單純註解,是讓CGI執行用的,不能忘了加"""
import sys
import cgi
import time
form = cgi.FieldStorage()

print("Content-type: text/html\n\n")
print("Hi, Python.
")
print("\n")
print(form["weblink"].value)

就把用chmod把python程式改成可執行
然後丟到CGI相關資料夾,通常是cgi-bin底下
接著就開瀏覽器去執行
結束!很簡單
所以這篇的重點不是說這個 XD

當完成上面的範例後,接著遇到的就是
如果要長時間的執行,那就必須要等待CGI程式跑完,不能關網頁
→那麼想辦法讓程式可以背景執行
→已經執行期間,給不了參數
→讓程式可以讀到網頁給的參數,甚至進行交握
→可以進行交握,可是正在運算時還是無法接受新的命令
→想辦法進行多執行緒化,讓程式可以平行作業
看來都可以解決,問題是…
怎麼做?

2018年5月19日 星期六

使用Python的urllib進行網頁資料的讀取

近來工作終於稍有喘息的空間
再來碰一下python吧,這次要學的,是網頁資料處理的urllib這個函式庫
也就是撰寫所謂的網路爬蟲程式

寫網路爬蟲程式會用到的模組是urllib模組其中的request
最簡單的使用法如下,以中央氣象局的網頁為例
import urllib.request as req
#以網址取得內容
response = req.urlopen("https://www.cwb.gov.tw/")
#顯示出抓取下來的內容
print(response.read())
然後就會看到中央氣象局的網頁原始碼(HTML)顯示在畫面上
這樣就成功了
接下來就是把讀下來的資料拿去HTMLParser分析然後抓出想要的資料了

可是不是每一個網頁都這麼好處理
有不少是希望你用瀏覽器去看,而不是單純抓資料下來
這時就會拒絕存取,顯示urllib.error.HTTPError: HTTP Error 403: Forbidden
該怎麼辦呢?這時候就需要加入Header資料去騙一下告訴伺服器
其實我是瀏覽器啦 XD

作法有兩種,一種直接在request的部分填入所需要的header資訊
import urllib.request as req
#以目標網址建立需求
header_request = req.Request("https://www.cwb.gov.tw/")
#需求加入開頭資訊,資訊名稱是User-Agent,內容是瀏覽器Chrome版本資訊
header_request.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36")
#用建立好的需求取得網址內容
response = req.urlopen(header_request)
#顯示抓取的內容
print(response.read())

另一種是建立handler與opener後,再開網頁
import urllib.request as req
#建立基本的Handler
handler = req.BaseHandler()
#以基本的Handler建立opener
opener = req.build_opener(handler)
#在opener裡面加入Header的資訊
opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36')]
#安裝opener到request裡
req.install_opener(opener)
#開啟目標網址
response = req.urlopen(url)
#顯示抓取的內容
print(response.read())

這樣看來,似乎第2個寫法比較麻煩多了
不過如果程式上需要以同一個header多抓幾個網址的話
那麼第2個寫法就顯得比較簡單,不用每一個網址都要再建一個帶有Header的Request
另外第2個寫法也可以解決需要帳號密碼的網頁
不過要加個密碼管理器
寫法如下:
import urllib.request as req
#建立基本的PasswordManager
pwdmgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
#加入網址、使用者帳號與密碼
pwdmgr.add_password(None,url ,user ,password)
#使用PasswordManager建立Handler
handler = req.HTTPBasicAuthHandler(pwdmgr)
#以下照舊,用Handler建opener
opener = req.build_opener(handler)
#在opener裡面加入Header的資訊
opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36')]
#安裝opener到request裡
req.install_opener(opener)
#開啟目標網址
response = req.urlopen(url)
#顯示抓取的內容
print(response.read())

基礎大概就這些了,剩下的都是變化形了
就我目前的使用來說,夠用了