Level2: 處理分頁
這次的目標網頁多了分頁的功能,因此我們的requests 就必須依據分頁的數量去存取,步驟如下:
- 設定n = 1
- 檢查第n頁有無資料,若有則下載網頁並轉換成DOM 格式,若無則輸出結果
- 解析、處理網頁內容
- 設定n = n+1,並回到第2步驟
由於import 的套件都一樣,所以只要修改main function即可。
1 2 3 4 5 6 7 8 9
| from lxml import etree import requests
def main(): pass
if __name__ == "__main__": main()
|
首先我們需要設定一個無窮迴圈,考慮現實情況下我們不一定知道目標網站共有幾頁的資料,不然也可以直接設定12圈來完成這題的目標:
無窮迴圈的話一定要給一個終止條件,所以我們先給一個很大的頁數並觀察沒有資料的網頁結構長怎樣
從網頁原始碼的結果得知,沒有資料的話網頁的 <table>
只有表頭而已,因此改良後的判斷條件如下:
1 2 3 4 5 6 7 8 9 10
| page = 1 while True: result = requests.get("http://axe-level-1.herokuapp.com/lv2?page=%s" % str(page)) result.encoding = 'utf8' root = etree.fromstring(result.text, etree.HTMLParser()) rows = root.xpath("//table[@class='table']/tr[position()>1]") if len(rows) == 0: break else: page+=1
|
由於有很多頁數, 所以 request
的目標必須是動態的字串,透過 rows
變數可以知道目前的資料列共有幾行,如果該頁沒有資料列的話表示已經到最後一頁了所以離開迴圈,若還沒到最後一頁我們就可以統計目前這頁的所有資料。
統計方法跟Level 1其實差不多,取得 <tr>
下的每個 <td>
,再把其結果分別儲存起來
1 2 3
| for row in rows: column = row.xpath("./td/text()") tmp = '{"town": "%s", "village": "%s", "name": "%s"},' % (column[0], column[1], column[2])
|
最後完整的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 etree import requests
def main(): page = 1 jsonData = '[' while True: result = requests.get("http://axe-level-1.herokuapp.com/lv2?page=%s" % str(page)) result.encoding = 'utf8' root = etree.fromstring(result.text, etree.HTMLParser()) rows = root.xpath("//table[@class='table']/tr[position()>1]") if len(rows) == 0: break else: tmp = "" for row in rows: column = row.xpath("./td/text()") tmp += '{"town": "%s", "village": "%s", "name": "%s"},' % (column[0], column[1], column[2]) jsonData += tmp page+=1 print(jsonData[0:-1] + "]")
if __name__ == "__main__": main()
|
這一章節就介紹到這邊結束,下一章節會介紹當網站有使用到SESSION 以及阻擋機器人情況下的爬蟲。