-1

我正在遍历 traceroute 中的 IP 地址数量并从 ip-api.com 获取地理位置数据,然后将已传递回的数据添加到名为 info 的变量中。

def toKML(iplist,namelist):
    kml = simplekml.Kml()
    x = 0 
    for ip in iplist:
        url =urllib2.Request('http://ip-api.com/json/' + str(ip)) #using API to gather geo info 

        info =json.load(urllib2.urlopen(url)) # setting data value to the feedback from the API for each IP
        if 'city' in info:
            print info['lon']
            kml.newpoint(name=str(info['city']),coords=[str(info['lon']),str(info['lat'])],description=(namelist[x]))
            x += 1
        else:
            print "Geo-locational data not found for the ip "+ ip +"."
            x +=1

    kml.save("test.kml")

API 返回的 JSON Object 示例如下:

{"as":"AS15169 Google Inc.","city":"Mountain View","country":"United    States","countryCode":"US","isp":"Google","lat":37.386,"lon":-122.0838,"org":"Google","query":"8.8.8.8","region":"CA","regionName":"California","status":"success","timezone":"America/Los_Angeles","zip":"94040"}

这会生成一个 KML 文档,但它没有正确解析坐标,这是 KML 文档的摘录:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
    <Document id="feat_1">
        <Placemark id="feat_2">
            <name/>
            <Point id="geom_0">
                <coordinates>-,0,. 5,1,.</coordinates>
            </Point>
            <description>sgyl-core-2b-ae7-717.network.virginmedia.net</description>
        </Placemark>

JSON对象中的坐标是正确的,因为当我在'info'中打印'lon'值时它返回:

-0.13 -0.0931 -0.0931 -0.13 -0.13 -0.13 -122.1826 -6.2597 -6.2597 -6.2597 -122.1822 -0.0931 -0.0931 -122.1822

错误存在于代码中:

kml.newpoint(name=str(info['city']),coords=[str(info['lon']),str(info['lat'])],description=(namelist[x]))

非常感谢您对此事的任何帮助。

4

1 回答 1

0

Ok, I think I deciphered some parts of your code. You need to fix several things:

  1. == is equality comparison operator. = is the assignment.
  2. do not use data.insert(x,info); x += 1 to add an item to a list, instead use just data.append(info)
  3. you read json (and it is parsed into a python dictionary) and store it into info variable:

    info = json.load(urllib2.urlopen(url))
    

    and then you put it into data list. So when you try to do:

    city[counter] == str(data['city'])
    

    (beside the == vs. = confusion), you're trying to index a list city with a counter, which is actually an item of data list, which is a dictionary, hence the error.

But I suspect there will be many other errors, it is probably impossible to help you with all of them.

EDIT1: I've tried to estimate how that code probably could look like (but of course, I don't know exactly what do you want..I'm guessing, since I'm not familiar with KML):

def toKML(iplist, namelist):
    kml = simplekml.KML()
    for ip, name in zip(iplist, namelist):
        url = urllib2.Request('http://ip-api.com/json/' + str(ip))
        info = json.load(urllib2.urlopen(url))
        kml.newpoint(name=str(info['city']),
                     coords=[(str(info['lon']), str(info['lat']))],
                     description=name)

    kml.save('test.kml') # don't know what this should do, but I'm guesing
                         # saving to a file?

Notes:

  • I'm not sure if you need to call str on every value - from what you've shown us, it looks like it's all strings already
  • I don't know if you really want to just save it or return it from that function?

EDIT 2: as for your problem with coordinates - I don't know what exactly you need to have in coords, but if your json looks ike you said it looks like, you're passing:

coords=[("-122.0838", "37.386")]

to the kml.newpoint function. I really do not know if that is correct or not. You should check what format is expected in this function and convert data appropriately.

Also - don't use that x to index namelist - it's unnecessary, it may cause problems if you're not careful - just use the zip as I've shown you (assuming that namelist and iplist have both the same length). If you don't know what zip does - it takes two lists and takes variables from the same positions in the lists when iterating. For example:

>>> for a, b in zip([1, 2, 3], ['a', 'b', 'c']):
...  print a, b
... 
1 a
2 b
3 c

Not only is it shorter, but also less error prone (you don't have to keep track of some index number).

Finally - I really, really, really recomend you to read some python tutorial and play with some simple problems in python before trying something more complex. The more you lear, the more fun you'll have with python, instead this suffering I see here. Good luck.

于 2015-03-16T15:50:01.843 回答