2010/08/01

lxml html

日本に割りあてられてる IP address が分かると嬉しいですよね
国内からならアクセスできるようにするとかできるようになります

ちょっとググると APNIC が日本に割りあててる IP address は
http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
に書いてあるもののようでした
IPv4 についても IPv6 についても書いてあります

で一方で国内っつったら APNIC よりは JPNIC でしょってことで
ちょっと JPNIC のページを探っていたんですがこんなのあったりして、ん〜、なんだこれはどうなってるんだ

で、何か違いがあるのかしら、と思って調べようと思ったんですが
JPNIC の方は table でこんなのどうしようかと
使ったことない lxml 使ってみることにしました
4 TopCoder: lxmlでHTMLスクレーピング
を見ながら

まぁだいたい 256 コ単位で割り振られてるんでしょうから
頭の3オクテット部分を列挙して diff 取ることにしましたよ
import math
import re
from urllib import urlopen

from lxml import html

def ip2int(ip):
return sum(
[256**x*int(y) for (x, y) in enumerate(reversed(ip.split('.')))])

def int2ip(n):
result = []
for i in range(4):
result.insert(0, str(n % 256))
n = n / 256
return ".".join(result)

classCs = set(())

for line in urlopen('http://ftp.apnic.net/stats/apnic/delegated-apnic-latest'):
rows = line.rstrip().split('|')
if len(rows) >= 4 and rows[1] == 'JP' and rows[2] == 'ipv4':
for i in range(int(rows[4])/256):
classCs.add(ip2int(rows[3])+256*i)

for url in ('http://www.nic.ad.jp/ja/dns/jp-addr-block.html',
'http://www.nic.ad.jp/ja/dns/ap-addr-block.html'):
root = html.fromstring(urlopen(url).read())
for (start, _, end) in [ [b.text for b in a.xpath('td')]
for a in root.xpath('//tr') ]:
tmp = ip2int(start)
end = ip2int(end)
while tmp < end:
classCs.add(tmp)
tmp += 256

for num in sorted(classCs):
print re.sub(r'\.[0-9]+$', '', int2ip(num))
使い捨てもいいところだ

で、こんな感じで2つ差分とってみましたところ
$ diff -u a.txt b.txt 
--- a.txt 2010-08-17 12:20:53.976666937 +0900
+++ b.txt 2010-08-17 12:14:20.992660340 +0900
@@ -554716,6 +554716,7 @@
203.190.61
203.190.62
203.190.63
+203.191.2
203.191.136
203.191.137
203.191.138
203.191.2?
そりゃいったい日本なのよどうなのよ
と思って上の delegated-apnic-latest を grep しみると
apnic|AU|ipv4|203.191.2.0|256|20060615|assigned
AU? オーストラリア??

まぁあとは WHOIS とか引いてみればいいわけですが
なんでオーストラリアかなぁ???