目录
查询了很多资料,找到了一些ip地址定位查询的接口,基本都是免费的
其中像高德地图、腾讯地图以及百度地图等都提供API接口,只需要注册他们的个人开发者账号即可调用。
因为我这边一共有45万个ip地址需要进行查询(在去重后也有40万+个),对比了这三家地图的api接口后发现 高德支持一天30万次请求,腾讯地图只支持1万次请求每天,百度地图就更少了低于1万次。
所以,我又找到了一家完全免费且不限请求次数的api接口,太平洋网络IP地址查询web接口(地址:http://whois.pconline.com.cn/)
太平洋网络IP地址查询接口示例:
import requests
import json
url = 'http://whois.pconline.com.cn/ipJson.jsp'
ip = '61.235.82.163'
param = {'ip':ip,
'json':'true'
}
ree = requests.get(url, params = param)
re = json.loads(ree.text.replace("\\"," "))
print(re)
输出结果如下:
{'ip': '61.235.82.163',
'pro': '广东省',
'proCode': '440000',
'city': '广州市',
'cityCode': '440100',
'region': '天河区',
'regionCode': '440106',
'addr': '广东省广州市天河区 蓝色心情网吧',
'regionNames': '',
'err': ''}
另外,高德地图API接口调用方式如下:
import requests
import json
url = 'https://restapi.amap.com/v3/ip?parameters'
ip = '61.235.82.163'
param = {'key':'你的key值',
'ip':ip,
'output':'JSON'
}
ree = requests.get(url, params = param)
re = json.loads(ree.text.replace("\\"," "))
print(re)
高德地图API接口还返回了该ip地址所在城市矩形区域范围
{'status': '1',
'info': 'OK',
'infocode': '10000',
'province': '广东省',
'city': '广州市',
'adcode': '440100',
'rectangle': '113.1017375,22.93212254;113.6770499,23.3809537'}
我试了一下,循环查询45万个ip地址定位,30分钟才跑完3万个左右。如果需要跑完全部,估计在8小时左右,简直太久了。然后一个朋友和我说,可以试试多线程或多进程。好熟悉的名词,但是我木有用过。。
于是,找来官方资料看了下,原来如此啊。于是,我便去尝试了下。果然,4核8 cpu都爆满了,最终45万个ip地址定位结果只用了1小时40余分钟。
静默状态下cpu使用情况
多进程下cpu使用情况
我们将ip地址数据拆分为6万每份共8份,然后循环每份数据进行ip地址定位查询
def Get_data(num,data):#获取ip地址定位
li = []
datax = data.iloc[(num-1)*60000:60000*num] #因为一共45万左右数据,按照6万每份进行分割
n = len(datax.index)
for _i in range(n):
ip = datax['ip'].iloc[_i]
param = {'ip':ip,
'json':'true'
}
try:
ree = requests.get(url, params = param)
re = json.loads(ree.text.replace("\\"," "))
logging.info(f"已经存储{_i+1}个ip及所在地")
li.append(re)
except json.decoder.JSONDecodeError:
logging.info(" param['ip']")
continue
return li
因为机器是4核8 cpu,这是为啥选择了8份的原因,然后调用进程池…
多进程的标准库
import multiprocessing
def main(page,data):#数据导出
logging.info('正在获取数据')
Li = Get_data(page,data)
logging.info('正在导出数据')
df = pd.DataFrame(Li)
e = r'E:\python\数据处理'
path = f'{e}\{page}.xlsx'
df.to_excel(path)
logging.info('数据计算完成!')
if __name__ == '__main__':
logging.info('正在读取原始数据')
data = pd.read_excel(r'E:\python\数据处理\每日新增用户.xlsx')
logging.info('原始数据读取完成')
pool = multiprocessing.Pool()
pages = range(1,9)
pool.map(partial(main,data=data),pages)
pool.close()
pool.join()
用multiprocess中的Pool起进程池,进程池中开启的个数:默认是cpu个数
map:可以拿到返回值的可迭代对象,循环就可以获取返回值了
这里除了map也用到了partial方法,因为main()需要传递2个参数,所以先用functools.partial将固定的参数值和main()进行绑定,然后再用map进行循环传参数page
同时有多个任务在执行:
采用pyecharts的map方法,传入城市及城市对应的数值,即可完成绘制
import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Map
df = df[['pro','city','ip']]
df = df.dropna()
data = pd.pivot_table(df,values='ip',index='city',aggfunc='count').reset_index()
data['city']=data['city'].apply(lambda x:x.replace("省",'').replace("市",''))
c = (
Map()
.add("注册玩家分布", [list(z) for z in zip(data['city'], data['ip'])], "china-cities",label_opts=opts.LabelOpts(is_show=False))
.set_global_opts(
title_opts=opts.TitleOpts(title="玩家分布"),
visualmap_opts=opts.VisualMapOpts(max_=5000),
)
)
c.width = '1200px'
c.height = '900px'
c.render('玩家城市分布.html')
城市分布图