Level3: 處理Session 雖然這次的目標也是有分頁,但是當切換頁面時並不像Level 2一樣是:&page=nnn 的形式
反而是透過 &page={prev,next} 這兩種值來決定要上一頁或者下一頁
題目已經很好心的告訴你我們要透過Session 來處理這題,在開始前先來聊聊Session 是什麼吧。
Session 是一種儲存在伺服端的資料, 用於儲存用戶資訊 以買飲料來舉例:
A 在飲料店點了一杯飲料
店員發給了A 一張號碼牌(cookie) 並且記住A 點了什麼飲料 (session)
A 拿號碼牌(cookie) 給店員,並且詢問飲料狀況
店員透過號碼牌查詢 POS 機(session) 後,確定飲料已經好了,再遞飲料給A
由上方的例子可以看出,Session 及 Cookie 是相對應的存在。
回到我們斧頭幫的網站,所以我們可以猜測伺服端的處理流程如下:
使用者連線進來,檢查 cookie 中的 PHPSESSID 是否有對應的SESSION
無對應:顯示第一頁,設定 $_SESSION[‘show’] = 1
有對應:檢查傳遞過來的page 參數是否為 next 或者 prev
沒有page 參數:讀取 $_SESSION[‘show’] 的值,並讀取相對應的值給使用者
page = next,設定 $_SESSION[‘show’] += 1,讀取下一頁的內容給使用者
page = prev,設定 $_SESSION[‘show’] -= 1,讀取上一頁的內容給使用者
了解網站的運作流程後就能開始寫程式拉。
與前面的寫法一樣, 只要修改 main function 即可:
1 2 3 4 5 6 7 from lxml import etreeimport requestsdef main () : pass if __name__ == "__main__" : main()
因為當讀取第一頁時,不需要給page參數,所以我們先把第一頁的及其他頁數的查詢分開處理
1 2 3 4 5 6 7 def main () : result = requests.get("http://axe-level-1.herokuapp.com/lv3/" ) result.encoding='utf-8' cookies = result.cookies for i in range(1 , 76 ): result = requests.post("http://axe-level-1.herokuapp.com/lv3/?page=next" , cookies=cookies) result.encoding = 'utf-8'
因為網站需要透過session 來處理頁面,所以我們必須把cookie 內的PHPSESSID 傳遞過去,如果不傳cookie的話,每次查詢的 ?page=next 都會是第二頁的結果,除非指定cookies,不然每次送出的post 都會是新的PHPSESSID。
流程寫好後就能開始處理資料了,我們另外寫一個parseTable 來整理資料
1 2 3 4 5 6 7 def parseTable (result) : root = etree.fromstring(result.text, etree.HTMLParser()) tmp = "" for row in root.xpath("//table[@class='table']/tr[position()>1]" ): column = row.xpath("./td/text()" ) tmp += '{"town": "%s", "village": "%s", "name": "%s"},' % (column[0 ], column[1 ], column[2 ]) return tmp
把全部的code 整理起來後如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 from lxml import etreeimport requestsdef main () : jsonData = '[' result = requests.get("http://axe-level-1.herokuapp.com/lv3/" ) result.encoding='utf-8' cookies = result.cookies jsonData += retriveToJson(result.text) for i in range(1 , 76 ): result = requests.post("http://axe-level-1.herokuapp.com/lv3/?page=next" , cookies=cookies) result.encoding = 'utf-8' jsonData += retriveToJson(result.text) print(jsonData[0 :-1 ] + "]" ) def parseTable (result) : root = etree.fromstring(result.text, etree.HTMLParser()) tmp = "" for row in root.xpath("//table[@class='table']/tr[position()>1]" ): column = row.xpath("./td/text()" ) tmp += '{"town": "%s", "village": "%s", "name": "%s"},' % (column[0 ], column[1 ], column[2 ]) return tmp if __name__ == "__main__" : main()
以上就是我們第三關的處理流程。