使用Python程序抓取新浪在国内的所有IP的教程

yipeiwu_com5年前Python爬虫

数据分析,特别是网站分析中需要对访问者的IP进行分析,分析IP中主要是区分来访者的省份+城市+行政区数据,考虑到目前纯真IP数据库并没有把这些数据做很好的区分,于是寻找了另外一个可行的方案(当然不是花钱买哈)。解决方案就是抓取新浪的IP数据。

新浪的IP数据接口为:
 
http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=123.124.2.85

返回的数据为:
 

复制代码 代码如下:

{"ret":1,"start":"123.123.221.0","end":"123.124.158.29","country":"\u4e2d\u56fd","province":"\u5317\u4eac","city":"\u5317\u4eac","district":"","isp":"\u8054\u901a","type":"","desc":""}

其返回的内容中已经包含了省份+城市+行政区信息了,这就是我们真实想要的。

下面就来说说如何来抓取这部分IP数据,要抓取这部分数据的主要工作就是枚举,即将接口中的IP不断的替换,要替换所有的IP地址肯定不太可能,所以我们缩小下范围,只穷举所有中国的IP段。考虑到新浪的IP接口返回的是IP段,所以要穷举的部分又少了一部分。再考虑啊到IP段的最后一位及256个IP基本上都是在一个地区,所以我们要穷举的数据有少了很多。对于穷举最重要的是把IP地址换成INT型。

具体国内有多少IP地址段,可以到APNIC官方网站去查找或下面的文档

http://ftp.apnic.net/apnic/dbase/data/country-ipv4.lst

下面就来看看穷举程序如何写:

 

import re

 
def ipv3_to_int(s):
  l = [int(i) for i in s.split('.')]
  return (l[0] << 16) | (l[1] << 8) | l[2]

 
def int_to_ipv3(s):
  ip1 = s >> 16 & 0xFF
  ip2 = s >> 8 & 0xFF
  ip3 = s & 0xFF
  return "%d.%d.%d" % (ip1, ip2, ip3)

 
i = open('ChinaIPAddress.csv', 'r')
list = i.readlines()
for iplist in list:
  pattern = re.compile('(\d{1,3}\.\d{1,3}\.\d{1,3})\.\d{1,3}')
  ips = pattern.findall(iplist)
  x = ips[0]
  y = ips[1]
  for ip in range (ipv3_to_int(x),ipv3_to_int(y)):
    ipadress=str(ip)
    #ip_address = int_to_ipv3(ip)
    o = open('ChinaIPAddress.txt','a')
    o.writelines(ipadress)
    o.writelines('\n')
  o.close()
i.close()

当上面的不走完成后就可以对新浪IP接口进行抓取了,抓取代码如下:
 

#!/usr/bin/python
# -*- coding: utf-8 -*-
import urllib,urllib2, simplejson, sqlite3, time

 
def ipv3_to_int(s):
  l = [int(i) for i in s.split('.')]
  return (l[0] << 16) | (l[1] << 8) | l[2]

 
def int_to_ipv4(s):
  ip1 = s >> 16 & 0xFF
  ip2 = s >> 8 & 0xFF
  ip3 = s & 0xFF
  return "%d.%d.%d.0" % (ip1, ip2, ip3)

 
def fetch(ipv4, **kwargs):
  kwargs.update({
    'ip': ipv4,
    'format': 'json',
  })
  DATA_BASE = "http://int.dpool.sina.com.cn/iplookup/iplookup.php"
  url = DATA_BASE + '?' + urllib.urlencode(kwargs)
  print url
  fails = 0
  try:
    result = simplejson.load(urllib2.urlopen(url,timeout=20))
  except (urllib2.URLError,IOError):
    fails += 1
    if fails < 10:
      result = fetch(ipv4)
    else:
      sleep_download_time = 60*10
      time.sleep(sleep_download_time)
      result = fetch(ipv4)
  return result

 
def dbcreate():
  c = conn.cursor()
  c.execute('''create table ipdata(
    ip integer primary key,
    ret integer,
    start text,
    end text,
    country text,
    province text,
    city text,
    district text,
    isp text,
    type text,
    desc text
  )''')
  conn.commit()
  c.close()

 
def dbinsert(ip,address):
  c = conn.cursor()
  c.execute('insert into ipdata values(?,?,?,?,?,?,?,?,?,?,?)',(ip,address['ret'],address['start'],address['end'],address['country'],address['province'],address['city'],address['district'],address['isp'],address['type'],address['desc']))
  conn.commit()
  c.close()

 
conn = sqlite3.connect('ipaddress.sqlite3.db')
dbcreate()

 
i = open('ChinaIPAddress.txt','r')
list = [s.strip() for s in i.readlines()]
end = 0
for ip in list:
  ip = int(ip)
  if ip > end :
    ipaddress = int_to_ipv4(ip)
    info = fetch(ipaddress)
    if info['ret'] == -1:
      pass
    else:
      dbinsert(ip,info)
      end = ipv3_to_int(info['end'])
      print ip,end
  else :
    pass
i.close()

到此就能把新浪所有的国内IP数据给抓取出来,然后在数据分析的工程中大派用场。~

相关文章

零基础写python爬虫之使用urllib2组件抓取网页内容

零基础写python爬虫之使用urllib2组件抓取网页内容

版本号:Python2.7.5,Python3改动较大,各位另寻教程。所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地。 类似于使用程序模拟IE浏览器...

python爬虫 猫眼电影和电影天堂数据csv和mysql存储过程解析

字符串常用方法 # 去掉左右空格 'hello world'.strip() # 'hello world' # 按指定字符切割 'hello world'.split(' ')...

python实现爬取图书封面

本文实例为大家分享了python实现爬取图书封面的具体代码,供大家参考,具体内容如下 kongfuzi.py 利用更换代理ip,延迟提交数据,设置请求头破解网站的反爬虫机制 impo...

selenium+python设置爬虫代理IP的方法

1. 背景 在使用selenium浏览器渲染技术,爬取网站信息时,一般来说,速度是很慢的。而且一般需要用到这种技术爬取的网站,反爬技术都比较厉害,对IP的访问频率应该有相当的限制。所以...

Scrapy基于selenium结合爬取淘宝的实例讲解

在对于淘宝,京东这类网站爬取数据时,通常直接使用发送请求拿回response数据,在解析获取想要的数据时比较难的,因为数据只有在浏览网页的时候才会动态加载,所以要想爬取淘宝京东上的数据,...