IPv6 學習筆記 003 – 從 Ripe NCC 擷取各國 ASes 的資料,以 Python 實作

簡述

Ripe NCC 的 IPv6 Enables Networks 可以看到圖表,代表各國的ASes 資料,預設是世界上所有國家的資料,可以自行選取想看到的國家。

圖表說明

橫軸是時間,每個月一個資料點,從2004年起。

縱軸是在 Ases資料中, IPv6 所佔百分比。

因此這可以作為一個「IPv6準備度」的量測指標之一。

ripencc

圖一、Ripe NCC 網頁的 Ases 資料圖

擷取資料

你會發現你沒辦法直接的複製這張圖,這是因為這張圖其實是直接在網頁上以 js 畫出來的,當你檢視原始碼時,你可以找到如下片段:

var store = new Ext.data.ArrayStore({
      fields: ['name', 'abbr', 'series'],
      idIndex: 0,
      data : [["Afghanistan, Islamic State of","AF",[[1086048000000,"0.000000","0...(後面很長,恕刪)
  });

注意關鍵字 data :之後的的資料,其實就是全部國家、全部區域的所有時間點資料。

這其實是個很棒的作法,因為即使是這麼多點的資料,加起來的流量也不會比一章圖大到哪裡去,而且這樣更加彈性,我們不必先畫好圖。

對於爬蟲們而言也更好,因為你不必把「圖表」跟「資料」分開思考。

以 Python 擷取

這段資料雖然不是常見的 json 格式,但是經由試驗,我使用 Python 的 json 模組,它看得懂這段資料,並且把資料存為多維度的 list 。

儲存的 Index 規則雖然要自己摸索一下,但也不會很難,你就親自把data展開,找找規律跟維度就行了,像這樣:

data : 
 [
   ["Afghanistan, Islamic State of","AF",
     [
        [1086048000000,"0.000000","0","1"],
        [1088640000000,"0.000000","0","1"],
        [1091318400000,"0.000000","0","1"],
         ...
        [1388534400000,"50.000000","1","2"]
     ]
   ]
   ,
   ["Andorra, Principality of","AD",
     [
        [1072915200000,"0.000000","0","1"],
        [1075593600000,"0.000000","0","1"],
        ...
...
...
...

怎麼樣? 其實很清楚吧?

擷取下來後,看你愛怎麼用就怎麼用,寫成文字檔、寫入MySQL 隨便你,以下是我的Python 範例程式碼,會把資料寫入一個文字檔:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Get ASes from http://v6asns.ripe.net/v/6.csv
# 2014 - Jan
# -----------------------------
import sys 
import urllib2
import json
import time
import datetime
# -----------------------------
# 抓網頁
# -----------------------------
htmlpage1 = urllib2.urlopen(r'http://v6asns.ripe.net/v/6.csv')
#hjson = json.loads(html.read())
# -----------------------------
# 讀網頁
# -----------------------------
htmlpage2 = htmlpage1.read()
# -----------------------------
# 尋找目標關鍵字
# var store = new Ext.data.ArrayStore({  data  });
# 找到以後把資料切出來
# 因為一下想不到要怎麼像 sed 可以只要一整行,所以我用笨方法
# -----------------------------
pos_start = htmlpage2.find("Ext.data.ArrayStore({")
htmlpage3 = htmlpage2[pos_start:]
pos_start = htmlpage3.find("data : [[")
pos_end = htmlpage3.find("]]]]")
htmlpage3 =  htmlpage3[pos_start:(pos_end+4)]
pos_start = htmlpage3.find("[[")
htmlpage3 =  htmlpage3[pos_start:]
# Now get the data
# -----------------------------
# 上吧 json !! :D
# json 的 loads 吃字串,所以直接餵進去
# -----------------------------
hj = json.loads(htmlpage3)
# -----------------------------
# 抓現在時間,拿來當成輸出的檔案名稱
# -----------------------------
nowts = time.time()
fstr= 'Ases'+str(nowts)+'.txt'
txtfile = open(fstr, 'w')
# -----------------------------
# hj 是個 list
# -----------------------------
for i in range(len(hj)):
 SN=i+1
 country=hj[i][0]
 # --------- 處理特殊國家名,有單引號者、連 UTF8 都沒有此字者 ----------
 country=country.replace('\'','\\\'')
 if (SN == 223):
    country="Aland Islands"
 # ---------------------------------------------------
 countrycode=hj[i][1]
 info =hj[i][2]
 # ---------------------------------
 #  每個國家的全部時間點輸出
 # --------------------------------
 for j in range(len(info)):
   # Get data
   ts=info[j][0]
   ts2=int(0.001*ts)
   date=datetime.datetime.fromtimestamp(ts2).strftime('%Y-%m-%d')
   percent=info[j][1]
   asnom=info[j][2]
   asdenom=info[j][3]
   str2 = "%s | %s | %s | %s | %s | %s\n"%(country, countrycode, date, asnom, asdenom, percent )
   txtfile.write(str2)
#---------------------------
# 結束,關閉檔案,收工!
#---------------------------
txtfile.close()
#--------------------------

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料