26 Ağustos 2009 Çarşamba

Ip Adresinden Şehir ve Ülkeyi Tespit Edelim

Kimi zaman sitemize ziyaretde bulunan kişinin yaşadığı ülkeye veya şehire göre yönlendirme yapmamız gerekebilir.
Bu çoğu webmasterin zaman zaman karşılaştığı  bir problemdir.

Bu konuyu biraz araştırdıktan sonra bir makale olarak ip adresinden ülke veya şehri nasıl tespit edebileceğimizi, 
tespit ettikten sonra da yönlendirme işlemlerinin nasıl olucağını, eğer istersek desktop programlarımız da kullanıcının 
dilini otomatik olarak olarak bulup buna göre de programın dilini nasıl değiştireceğimizi anlatacağım.

Uzun bir başlangıç oldu sanırım. Lafı uzatmadan konuyu biraz açayım. Ip adresinden yer tespiti yapabilmemiz için ya ip aralıklarının bulunduğu bir database'e sahip olmamız
yada database'e sahip olup bunu api olarak kullanmamıza imkan veren sistemden yararlanmak gerekiyor. Ben 2. yolu da anlatacağım, sırf ülkeye göre yönlendirme yapmak için
koca database'yi kullanmayı istemeyiz değli mi ?

Araştırmalarım sonucunda ücretsiz olarak api hizmeti veren bir site buldum.

Sorgularımızın çıktısını xml olarak alabiliyoruz.

http://ipinfodb.com/ip_query.php?ip=78.168.16.23
sayfanın çıktısı şu şekilde oluyor
<?xml version="1.0" encoding="UTF-8"?>
<Response>
 <Ip>78.168.16.23</Ip>
 <Status>OK</Status>
 <CountryCode>TR</CountryCode>
 <CountryName>Turkey</CountryName>
 <RegionCode>71</RegionCode>
 <RegionName>Konya</RegionName>
 <City>Konya</City>
 <ZipPostalCode></ZipPostalCode>
 <Latitude>37.8656</Latitude>
 <Longitude>32.4825</Longitude>
 <Gmtoffset>2.0</Gmtoffset>
 <Dstoffset>3.0</Dstoffset>
</Response>
Ben size php ile almayı göstereceğim. Zaten diğer dillerde de aynı mantık.
php 5 ile gelen yeniliklerden bir taneside "simplexml_load_file" fonksiyonudur. Adı üzerinde, xml ile ilgili basit işlemlerimizde kullanıcağız.

Not: "simplexml_load_file" fonksiyonunu localde bulunmayan dosyalarda kullanabilmemiz için php.ini dosyasında "allow_fopen_url" değerinin "on" olması gerekiyor.
<?
$xml = simplexml_load_file("http://ipinfodb.com/ip_query.php?ip=78.168.16.23");
print_R($xml);
?>
kodun çıktısı şu şekilde olucak
SimpleXMLElement Object
(
    [Ip] => 78.168.16.23
    [Status] => OK
    [CountryCode] => TR
    [CountryName] => Turkey
    [RegionCode] => 71
    [RegionName] => Konya
    [City] => Konya
    [ZipPostalCode] => SimpleXMLElement Object
        (
        )

    [Latitude] => 37.8656
    [Longitude] => 32.4825
    [Gmtoffset] => 2.0
    [Dstoffset] => 3.0
)
Gördüğünüz gibi Object şeklinde bize döndü.
<?
$xml = simplexml_load_file("http://ipinfodb.com/ip_query.php?ip=78.168.16.23");
echo $xml->City; //Şehir
echo "\n";
echo $xml->CountryName;
echo "\n";
echo $xml->CountryCode;
?>
Yukarıdaki kodlarla ülkeyi ve şehri yazdırdık. php 5 öncesi kullananlar için curl ile yaptığım örneği göstereyim.
<?
$ip=$_SERVER["REMOTE_ADDR"];
$curl_oturumu =curl_init("http://ipinfodb.com/ip_query.php?ip=$ip");
curl_setopt($curl_oturumu, CURLOPT_HEADER, 0);
curl_setopt($curl_oturumu, CURLOPT_RETURNTRANSFER ,1);
$calistir= curl_exec($curl_oturumu);
curl_close($curl_oturumu); 
$desc = '#<City>(.*?)</City>#si';
$desc2 = '#<CountryName>(.*?)</CountryName>#si';
$desc3='#<CountryCode>(.*?)</CountryCode>#si';
preg_match_all($desc,$calistir,$asim);
preg_match_all($desc2,$calistir,$asim2);
preg_match_all($desc3,$calistir,$asim3);
$ulke=$asim[1][0];
$sehir=$asim2[1][0];
$ulkekodu=$asim3[1][0];
?>
İstersek countrycode u bir cookieye atıp ufak bir kontrol ile ziyaretçinin ülkesine göre istediğimiz sayfaya yönlendirebiliriz. Cookie olarak atadığımız için, yazdığımız ufak kontrol sayesinde ziyaretçi sitenizi tekrar ziyaret ettiğinde kendi dilinin bulunduğu sayfaya yönlenicektir. Yapabileceklerimizin sınırları bu değli tabi ki. Bir masaüstü programı düşünün. Programınızı farklı ülkelerdeki kişiler kullanıyor ve birden fazla dil seçeneğiniz mevcut.Program ilk açıldığında default language ile başlıyor. Peki programınızın açılışında kullanıcının ülkesini otomatik olarak tespit programın dilini ona göre ayarlamak istemez misiniz? Ben size örnek olarak c#'da göstericeğim.
using System.XML;

XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("http://ipinfodb.com/ip_query.php?ip=78.168.16.23");
string ulkekodu= xmldoc.GetElementsByTagName("CountryCode").Item(0).InnerText.ToLower();
.ToLower() ile küçük harflere çevirdik çünkü ülke bayrakları http://ipinfodb.com/img/flags/ adresinde ulkekodu.gif şeklinde bulunuyor. Bundan sonrası dil değiştirme kodlarınız ile yukarıdaki kodları entegre bir biçimde kullanmanıza bağlı. Ülkeye ait bayrağı ise ufak bir picturebox sayesinde formunuzun herhangi bir yerinde gösterebilirsiniz. Yukarıda da dediğim gibi yapabileceklerimizin sınırları hayal gücünüze bağlıdır her zaman. Eğer istersek ufak bir bash script ile serverımızın kapılarını bir ülkeye kapatabiliriz.
#!/bin/bash
###IPINFODB.COM###
 
###PUT HERE COMA SEPARATED LIST OF COUNTRY CODE###
COUNTRIES="AK,AR"
WORKDIR="/home/someuser"
#######################################
 
cd $WORKDIR
wget -c --output-document=iptables-blocklist.txt http://ipinfodb.com/country_query.php?country=$COUNTRIES
if [ -f iptables-blocklist.txt ]; then
  iptables -F
  BLOCKDB="iptables-blocklist.txt"
  IPS=$(grep -Ev "^#" $BLOCKDB)
  for i in $IPS
  do
    iptables -A INPUT -s $i -j DROP
    iptables -A OUTPUT -d $i -j DROP
  done
fi
rm -f $WORKDIR/iptables-blocklist.txt
iptables kullanmadan .htaccess ile de bunu yapabiliriz. Daha ayrıntılı bilgi için api hizmetini sunan http://ipinfodb.com adresini ziyaret edin. #Düzenleme Tuğrul arkadaşım makalenin c# için olanını yazmış. Dilerseniz aşağıdaki linkten ulaşabilirsiniz. http://www.tugrulalpdogan.com/2010/03/ip-adresinden-sehir-ve-ulkeyi-tespit_02.html

3 yorum:

Adsız dedi ki...

Çok güzel ve detaylı bir yazı olmuş, teşekkürler.

Adsız dedi ki...

Çok hoşuma gitti asım teşekkürler.

dunkof dedi ki...

türkiye şartlarında bunda stabil veri elde etmek pek mümkün değil.

Yorum Gönder

Yorumlarınızı adsız olarak yapmamanız konuya olan ilgi ve samimiyetinizi göstericektir