将 KML 解析为 Google 地图仅显示数百个图钉中的一个

Parsing KML to Google Maps only shows one of hundreds of pins

我的期望

我正在研究 Violent Python,目前我正在一个模块中从 .pcap-file 中获取 ip-addresses,解析 ip-addresses到经度和纬度,最后将这些 longs 和 langs 解析为 .kml 文件。

我的想法是我的 .kml 文件应该可以上传到 Google 地球和 Google 地图,以显示每个捕获包的来源和目的地的引脚。


实际发生了什么:

Parsing Aborted


代码和其他重要内容z:

您可以找到 whole .kml-file here.

headers 是正确的(如果相信本书和其他 SO 线程):

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">

所有地标都具有以下简单结构:

<Placemark>
    <name>212.204.214.114</name>
    <Point>
        <coordinates>4.834300, 52.404800</coordinates>
    </Point>
</Placemark>

我的代码遵循与 Violent Python 中的模块相同的结构,有一些小的变化以更好地遵循更现代的最佳实践:

import dpkt, socket, pygeoip, argparse, os

gi = pygeoip.GeoIP('/opt/GeoIP/Geo.dat')

def ret_klm(ip):
    rec = gi.record_by_name(ip)

    try:
        long = rec['longitude']
        lat  = rec['latitude']
        kml = (
            '<Placemark>\n'
            '<name>%s</name>\n'
            '<Point>\n'
            '<coordinates>%6f, %6f</coordinates>\n'
            '</Point>\n'
            '</Placemark>\n'
            )%(ip, long, lat)
        return kml
    except:
        return ''


def plotIPs(pcap):
    kml_points = ''
    for (ts, buf) in pcap:
        try:
            eth = dpkt.ethernet.Ethernet(buf)
            ip  = eth.data
            src = socket.inet_ntoa(ip.src)
            src_kml = ret_klm(src)
            dst = socket.inet_ntoa(ip.dst)
            dst_kml = ret_klm(dst)
            kml_points = kml_points + src_kml + dst_kml
        except:
            pass

    return kml_points

def main():

    parser = argparse.ArgumentParser(
        description=u'GeoLocator to parse IP addresses to their '
                    u'long, lat in KML for Google Maps.'
    )

    parser.add_argument(
        u'-p',
        help=u'Pcap file for parsing',
        required=True,
        dest=u'pcap_file'
    )
    arguments = parser.parse_args()

    if not os.path.isfile(arguments.pcap_file):
        parser.print_usage()
        raise SystemExit

    with open(arguments.pcap_file) as file:
        pcap = dpkt.pcap.Reader(file)
        kmlheader = '<?xml version="1.0" encoding="UTF-8"?>'+\
            '\n<kml xmlns="http://www.opengis.net/kml/2.2">\n'
        kmlfooter = '</kml>\n'
        kmldoc = kmlheader + plotIPs(pcap) + kmlfooter
        print(kmldoc)

if __name__ == '__main__':
    main()

您需要将 元素添加到您的 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" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <Placemark>
        <name>212.204.214.114</name>
        <Point>
            <coordinates>4.834300, 52.404800</coordinates>
        </Point>
    </Placemark>
    <Placemark>
        <name>212.204.214.114</name>
        <Point>
            <coordinates>4.834300, 52.404800</coordinates>
        </Point>
    </Placemark>
    <!-- the rest of your placemarks -->
</Document>
</kml>