简体   繁体   English

如何在 Python 中使用 IP 地址查找位置?

[英]How to find location with IP address in Python?

I am developing a project, that needs to store user location in my data base.我正在开发一个项目,需要将用户位置存储在我的数据库中。 I got the public IP address of that user.我得到了那个用户的公共 IP 地址。 But I am unable to get the user location.但我无法获取用户位置。 I have tried several ways (from StackOverflow ) but I didn't find any hint.我尝试了几种方法(来自StackOverflow ),但没有找到任何提示。 Like the below像下面这样

url = urllib.urlopen("http://api.hostip.info/get_html.php?ip=%s&position=true" % ip)
data = re.compile('^[^\(]+\(|\)$').sub('', url.read())
print data

but I am getting the result as但我得到的结果是

Unknown Country?) (XX)
City: (Unknown City?)

another way:其它的办法:

import urllib

response = urllib.urlopen("http://api.hostip.info/get_html.php?ip={}&position=true".format(ip)).read()

print(response)

but the result is但结果是

Country: (Unknown Country?) (XX)
City: (Unknown City?)

Latitude: 
Longitude: 
IP: 115.xxx.xxx.xx

Any help would be appreciated!任何帮助,将不胜感激!

One of the simplest methods for getting the IP address as well as the location in detail is to use http://ipinfo.io获取 IP 地址和详细位置的最简单方法之一是使用http://ipinfo.io

import re
import json
from urllib2 import urlopen

url = 'http://ipinfo.io/json'
response = urlopen(url)
data = json.load(response)

IP=data['ip']
org=data['org']
city = data['city']
country=data['country']
region=data['region']

print 'Your IP detail\n '
print 'IP : {4} \nRegion : {1} \nCountry : {2} \nCity : {3} \nOrg : {0}'.format(org,region,country,city,IP)

Try with pygeoip尝试使用pygeoip

~$ ping stackoverflow.com
PING stackoverflow.com (198.252.206.16) 56(84) bytes of data.

>>> import pygeoip
>>> GEOIP = pygeoip.GeoIP("/absolute_path/GeoIP.dat", pygeoip.MEMORY_CACHE)
>>> GEOIP.country_name_by_addr(ip)
'United States'

GeoIP.data is available here GeoIP.data 可在此处获得

for python-3.x对于 python-3.x

def ipInfo(addr=''):
    from urllib.request import urlopen
    from json import load
    if addr == '':
        url = 'https://ipinfo.io/json'
    else:
        url = 'https://ipinfo.io/' + addr + '/json'
    res = urlopen(url)
    #response from url(if res==None then check connection)
    data = load(res)
    #will load the json response into data
    for attr in data.keys():
        #will print the data line by line
        print(attr,' '*13+'\t->\t',data[attr])

Thanks for all the solutions and workarounds!感谢所有解决方案和解决方法! However, I was not able to use all of the above methods.但是,我无法使用上述所有方法。

Here is what worked for me:这是对我有用的:

import requests

response = requests.get("https://geolocation-db.com/json/39.110.142.79&position=true").json()

This method seemed simple and easy to use.这种方法看起来简单易用。 (I needed to work with a dictionary response...) (我需要使用字典响应...)

In the future, the "geolocation-db.com" might become unavailable, so alternative sources might be required!将来,“geolocation-db.com”可能会变得不可用,因此可能需要其他来源!

Assuming that you got the ip address already, you can try to use the IP2Location Python Library to get the user location.假设您已经获得了ip地址,您可以尝试使用IP2Location Python库来获取用户位置。 A sample code is like this:一个示例代码是这样的:

import os
import IP2Location

database = IP2Location.IP2Location(os.path.join("data", "IPV4-COUNTRY.BIN"))

rec = database.get_all(ip)

print(rec.country_short)
print(rec.country_long)
print(rec.region)
print(rec.city)
print(rec.isp)  
print(rec.latitude)
print(rec.longitude)            
print(rec.domain)
print(rec.zipcode)
print(rec.timezone)
print(rec.netspeed)
print(rec.idd_code)
print(rec.area_code)
print(rec.weather_code)
print(rec.weather_name)
print(rec.mcc)
print(rec.mnc)
print(rec.mobile_brand)
print(rec.elevation)
print(rec.usage_type)

Depends on your requirement, for example if you want to get the user's country name and region name, you can do this:取决于您的要求,例如如果您想获取用户的国家名称和地区名称,您可以这样做:

import os
import IP2Location

database = IP2Location.IP2Location(os.path.join("data", "IPV4-COUNTRY.BIN"))

rec = database.get_all(ip)

user_country = rec.country_long
user_region = rec.region

For more details, you can visit here: IP2Location Python library更多详细信息,您可以访问这里: IP2Location Python 库

Github link: IP2Location Python library Github Github 链接: IP2Location Python 库 Github

You can use the services of https://geolocation-db.com IPv4 and IPv6 are supported.您可以使用https://geolocation-db.com的服务支持 IPv4 和 IPv6。 Either a JSON-object or JSONP callback function is returned.返回 JSON 对象或 JSONP 回调函数。

Python 2:蟒蛇2:

import urllib
import json

url = "https://geolocation-db.com/json"
response = urllib.urlopen(url)
data = json.loads(response.read())
print data

Python 3:蟒蛇3:

import urllib.request
import json

with urllib.request.urlopen("https://geolocation-db.com/json") as url:
    data = json.loads(url.read().decode())
    print(data)

A python 3 jsonp example:一个 python 3 jsonp 示例:

import urllib.request
import json

with urllib.request.urlopen("https://geolocation-db.com/jsonp/8.8.8.8") as url:
    data = url.read().decode()
    data = data.split("(")[1].strip(")")
    print(data)

I'm doing this same thing on own server.我在自己的服务器上做同样的事情。 Get an API key from http://ipinfodb.com/register.php and try:http://ipinfodb.com/register.php获取 API 密钥并尝试:

import requests

ipdb = "http://api.ipinfodb.com/v3/ip-city/?key=<your api key>&ip="
ip_address = function_to_get_ip_address()
location = " ".join(str(requests.get(ipdb+ip_address).text).split(";")[4:7])

The value of location will be COUNTRY REGION CITY . location的值将是COUNTRY REGION CITY

Keep in mind that IP addresses are not precise geo-locators.请记住,IP 地址不是精确的地理定位器。 Especially when accessing your website from a mobile device, you'll see that the location of the IP address to be maybe 100 miles away from the physical location of the user.尤其是从移动设备访问您的网站时,您会看到 IP 地址的位置可能距离用户的物理位置 100 英里。

It ultimately depends on how you get your computers IP address.这最终取决于您如何获取计算机 IP 地址。 If you are on a VPN or another private network, just getting the local IP address will return nothing, like you are seeing now.如果您使用的是 VPN 或其他专用网络,则仅获取本地 IP 地址将不会返回任何内容,就像您现在看到的那样。 In this case you have to get the public IP address like so:在这种情况下,您必须像这样获取公共 IP 地址:

url = 'http://api.hostip.info/get_json.php'
info = json.loads(urllib.urlopen(url).read())
ip = info['ip']

Here is my full code for getting all the information that you are seeking (I used freegeoip.net):这是我获取您正在寻找的所有信息的完整代码(我使用了 freegeoip.net):

import urllib
import json

url = 'http://api.hostip.info/get_json.php'
info = json.loads(urllib.urlopen(url).read())
ip = info['ip']

urlFoLaction = "http://www.freegeoip.net/json/{0}".format(ip)
locationInfo = json.loads(urllib.urlopen(urlFoLaction).read())
print 'Country: ' + locationInfo['country_name']
print 'City: ' + locationInfo['city']
print ''
print 'Latitude: ' + str(locationInfo['latitude'])
print 'Longitude: ' + str(locationInfo['longitude'])
print 'IP: ' + str(locationInfo['ip'])

requirements:要求:

sudo add-apt-repository ppa:maxmind/ppa
sudo apt update
sudo apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
sudo pip install geoip2

geoip database:地理数据库:

wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
tar xvfz GeoLite2-City.tar.gz

example for nginx access logs: nginx 访问日志示例:

python -c 'import geoip2.database
reader = geoip2.database.Reader("./GeoLite2-City/GeoLite2-City.mmdb")
for line in open("/var/log/nginx/access.log').readlines():
    response = reader.city(line.split(" ")[0])
    print(dir(response))
'

related:有关的:

I found ipinfo offering the best service and providing free API usage for up to 50k calls per month - see 'Rate Limits' here :我发现 ipinfo 提供最好的服务,并为每月最多 50k 次调用提供免费 API 使用 - 请参阅此处的“速率限制”:

import ipinfo

access_token = '123456789abc'
handler = ipinfo.getHandler(access_token)
ip_address = '216.239.36.21'
details = handler.getDetails(ip_address)
details.city
'Mountain View'
details.country
'US'
details.loc
'37.3861,-122.0840'

https://github.com/airakesh/BeautifulSoupRecipes/blob/master/geoip.py https://github.com/airakesh/BeautifulSoupRecipes/blob/master/geoip.py

# Get Geolocation(Country) and hostname by passing a file having a bunch of IP addresses as the argument from the command line. Example- python GeoIP.py path-to-file-containing-IP addresses:
https://github.com/airakesh/BeautifulSoupRecipes/blob/master/sample_ips.txt

import re
import os
import sys
import subprocess
import socket

# Input file argument
ips_file = sys.argv[1]

# The regular expression for validating an IP-address                                                                                                                                                            
pattern = '''^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)'''

def getGeoHost():
    fp = open(ips_file, 'rb')
    for line in fp:
        line = line.strip()
        addr = line.decode('utf-8')
        regex = re.compile(pattern)
        match = regex.match(addr)
        # Get hostname by IP address                                                                                                                                                                          
        try:
            host = socket.gethostbyaddr(addr)
            hostname = host[0]
        # Print Unknown no hostname is available                                                                                                                                                                  
        except:
            hostname = 'Unknown'

        # Get geolocation by IP address                                                                                                                                                                            
        get_geo_cmd = 'geoiplookup ' + addr
        geo_str = subprocess.check_output(get_geo_cmd, shell=True)
        geo = geo_str.decode('utf-8')

        # Match country name pattern                                                                                                                                                                              
        geo_pattern = '''^(GeoIP Country Edition: ([A-Z]{2})\, (.*))'''
        geo_regex = re.compile(geo_pattern)
        country_match = re.match(geo_pattern, geo)
        # Check country name is available and if not, print 'Unknown'                                                                                                                                               
        if country_match != '' and geo_pattern:
            try:
                country = country_match.group(3)
            except:
                country = 'Unknown'
        # Clubbing together in format 'IP|Country|Hostname' data                                                                                                                                                    
        geo_hostname = addr + ' | ' + country + ' | ' + hostname
        print geo_hostname


if __name__ == "__main__":

    ips_detail_list = getGeoHost()

You can do that using ipinfo's api first go to ipinfo.io and sign up.您可以使用 ipinfo 的 api 首先访问ipinfo.io并注册。 You'll get a access token, copy it, now do pip install ipinfo now you can type this sample code:您将获得访问令牌,复制它,现在执行pip install ipinfo现在您可以键入以下示例代码:

>>> import ipinfo
>>> handler = ipinfo.getHandler(access_token)
>>> d = handler.getDetails(ip_address)
>>> d.city

or if you'll directly do d.details it will return a dictionary and you could use it as a dictionary too, it would have all things like ip address, city, country, state etc. you can also get them using like this d.country or for location d.loc , for city, as i wrote, d.city或者,如果您直接执行d.details它将返回一个字典,您也可以将其用作字典,它将包含所有内容,例如 IP 地址、城市、国家/地区、州等。您也可以像这样使用它们d.country或位置d.loc ,如我所写的城市, d.city

nmap --script ip-geolocation-geoplugin <target>
Script Output
| ip-geolocation-geoplugin:
| coordinates: 39.4208984375, -74.497703552246
|_location: New Jersey, United States

https://nmap.org/nsedoc/scripts/ip-geolocation-geoplugin.html https://nmap.org/nsedoc/scripts/ip-geolocation-geoplugin.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM