-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 オブジェクトの例は次のとおりです。

{"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>

「info」内の「lon」値を出力すると、JSON オブジェクト内の座標が正しくなり、次のように返されます。

-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 に答える