Çevrimiçi bir API'ya erişip erişemediğimi görmek istiyorum, ancak bunun için İnternet erişimim olması gerekiyor.
Python kullanarak kullanılabilir ve etkin bir bağlantı olup olmadığını nasıl görebilirim?
easy_install system_of_tubes
Çevrimiçi bir API'ya erişip erişemediğimi görmek istiyorum, ancak bunun için İnternet erişimim olması gerekiyor.
Python kullanarak kullanılabilir ve etkin bir bağlantı olup olmadığını nasıl görebilirim?
easy_install system_of_tubes
Yanıtlar:
Belki böyle bir şey kullanabilirsiniz:
import urllib2
def internet_on():
try:
urllib2.urlopen('http://216.58.192.142', timeout=1)
return True
except urllib2.URLError as err:
return False
Şu anda, 216.58.192.142 google.com için IP adreslerinden biridir. Hızlı bir şekilde yanıt vermesi beklenen herhangi bir sitede değişiklik http://216.58.192.142
yapın .
Bu sabit IP sonsuza kadar google.com ile eşleşmez. Bu nedenle bu kod sağlam değildir - çalışmasını sağlamak için sürekli bakıma ihtiyaç duyar.
Yukarıdaki kodun tam etki alanı adı (FQDN) yerine sabit bir IP adresi kullanmasının nedeni, FQDN'nin DNS araması gerektirmesidir. Makinenin çalışan bir internet bağlantısı yoksa, DNS aramasının kendisi urllib_request.urlopen
bir saniyeden uzun bir süredir çağrıyı engelleyebilir . @ Rzetterberg'e bunu işaret ettiği için teşekkürler.
Yukarıdaki sabit IP adresi çalışmıyorsa, çalıştırarak google.com (unix'te) için geçerli bir IP adresi bulabilirsiniz
% dig google.com +trace
...
google.com. 300 IN A 216.58.192.142
urlopen
internet" açık "olmasa bile için çağrı 1 saniyeden daha uzun sürmez. - alıntı. Sağlanan url geçersizse bu doğru değildir, o zaman DNS araması engellenir. Yalnızca web sunucusuna gerçek bağlantı için geçerlidir. Bu DNS arama bloğunu önlemenin en basit yolu IP adresini kullanmaktır, o zaman sadece 1 saniye sürmesi garanti edilir :)
http://google.com
ve sonra herkesin burada konuşmaya devam ettiği tüm sorunları çözersin. IP adresi kullanmaya gerek yok ...
Bazı İnternet sunucularına bağlanabiliyorsak, aslında bağlantımız var. Bununla birlikte, en hızlı ve en güvenilir yaklaşım için, tüm çözümler en azından aşağıdaki gereksinimlere uymalıdır:
Bunlara uymak için bir yaklaşım, Google'ın genel DNS sunucularından birinin erişilebilir olup olmadığını kontrol etmek olabilir . Bu sunucular için IPv4 adresleri 8.8.8.8
ve8.8.4.4
. Bunlardan herhangi birine bağlanmayı deneyebiliriz.
Ev sahibinin hızlı bir Nmap 8.8.8.8
aşağıdaki sonucu verdi:
$ sudo nmap 8.8.8.8
Starting Nmap 6.40 ( http://nmap.org ) at 2015-10-14 10:17 IST
Nmap scan report for google-public-dns-a.google.com (8.8.8.8)
Host is up (0.0048s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
53/tcp open domain
Nmap done: 1 IP address (1 host up) scanned in 23.81 seconds
Gördüğümüz gibi 53/tcp
, açık ve filtrelenmemiş. Olmayan bir kök kullanıcı iseniz, kullanmayı unutmayın sudo
veya-Pn
Nmap için hazırlanmış prob paketleri göndermek ve bir ana bilgisayarın hazır olup olmadığını belirlemek argümanı .
Python ile denemeden önce, harici bir araç olan Netcat kullanarak bağlantıyı test edelim:
$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!
Netcat onaylar biz ulaşabilmesi 8.8.8.8
üzerinde 53/tcp
. Şimdi bağlantıyı 8.8.8.8:53/tcp
kontrol etmek için Python'da bir soket bağlantısı kurabiliriz :
import socket
def internet(host="8.8.8.8", port=53, timeout=3):
"""
Host: 8.8.8.8 (google-public-dns-a.google.com)
OpenPort: 53/tcp
Service: domain (DNS/TCP)
"""
try:
socket.setdefaulttimeout(timeout)
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
return True
except socket.error as ex:
print(ex)
return False
internet()
Başka bir yaklaşım, bu sunuculardan birine manuel olarak hazırlanmış bir DNS probu göndermek ve bir yanıt beklemek olabilir. Ancak, paket düşüşleri, DNS çözümleme hatası vb.Nedenlerle karşılaştırıldığında daha yavaş olabileceğini düşünüyorum. Aksi düşünürseniz lütfen yorum yapın.
GÜNCELLEME 1: @ theamk'nin yorumu sayesinde, zaman aşımı artık bir argüman ve 3s
varsayılan olarak başlatıldı .
GÜNCELLEME # 2: Bu soruya verilen tüm geçerli cevapların en hızlı ve en genel uygulamasını belirlemek için hızlı testler yaptım. İşte özet:
$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.487
iamaziz.py
True
00:00:00:00.335
ivelin.py
True
00:00:00:00.105
jaredb.py
True
00:00:00:00.533
kevinc.py
True
00:00:00:00.295
unutbu.py
True
00:00:00:00.546
7h3rAm.py
True
00:00:00:00.032
Ve bir kez daha:
$ ls *.py | sort -n | xargs -I % sh -c 'echo %; ./timeit.sh %; echo'
defos.py
True
00:00:00:00.450
iamaziz.py
True
00:00:00:00.358
ivelin.py
True
00:00:00:00.099
jaredb.py
True
00:00:00:00.585
kevinc.py
True
00:00:00:00.492
unutbu.py
True
00:00:00:00.485
7h3rAm.py
True
00:00:00:00.035
True
Yukarıdaki çıktıda, ilgili yazarlardan gelen tüm bu uygulamaların İnternet bağlantısını doğru şekilde tanımladığı belirtilmektedir. Zaman milisaniye çözünürlükte gösterilir.
GÜNCELLEME # 3: İstisna işleme değişikliğinden sonra tekrar test edildi:
defos.py
True
00:00:00:00.410
iamaziz.py
True
00:00:00:00.240
ivelin.py
True
00:00:00:00.109
jaredb.py
True
00:00:00:00.520
kevinc.py
True
00:00:00:00.317
unutbu.py
True
00:00:00:00.436
7h3rAm.py
True
00:00:00:00.030
close()
Soketi aramamalı mıyız ?
Sadece bir HEAD isteği yapmak daha hızlı olur, böylece HTML getirilmez.
Ayrıca eminim google bu şekilde daha iyi istiyorum :)
try:
import httplib
except:
import http.client as httplib
def have_internet():
conn = httplib.HTTPConnection("www.google.com", timeout=5)
try:
conn.request("HEAD", "/")
conn.close()
return True
except:
conn.close()
return False
Ubutnu / Kevin C cevaplarına alternatif olarak, requests
paketi şu şekilde kullanıyorum:
import requests
def connected_to_internet(url='http://www.google.com/', timeout=5):
try:
_ = requests.get(url, timeout=timeout)
return True
except requests.ConnectionError:
print("No internet connection available.")
return False
Bonus: Bu, bir web sitesine ping yapan bu işleve genişletilebilir.
def web_site_online(url='http://www.google.com/', timeout=5):
try:
req = requests.get(url, timeout=timeout)
# HTTP errors are not raised by default, this statement does that
req.raise_for_status()
return True
except requests.HTTPError as e:
print("Checking internet connection failed, status code {0}.".format(
e.response.status_code))
except requests.ConnectionError:
print("No internet connection available.")
return False
google.com
tekrar pining yaparsanız , IP adresimizi bloke ederler. Başka yolu var mı?
Sadece unutbu'nun Python 3.2'deki yeni kod için söylediklerini güncellemek için
def check_connectivity(reference):
try:
urllib.request.urlopen(reference, timeout=1)
return True
except urllib.request.URLError:
return False
Ve sadece not etmek gerekirse, buradaki giriş (referans) kontrol etmek istediğiniz url'dir: Yaşadığınız yerde hızlı bağlanan bir şey seçmenizi öneririm - yani Güney Kore'de yaşıyorum, bu yüzden muhtemelen http: / /www.naver.com .
Sadece veri indirmeyi deneyebilirsiniz ve bağlantı başarısız olursa, bağlantıya sahip olan şeylerin iyi olmadığını bilirsiniz.
Temel olarak bilgisayarın internete bağlı olup olmadığını kontrol edemezsiniz. Hatalı DNS yapılandırması, güvenlik duvarları, NAT gibi birçok hata nedeni olabilir. Bu nedenle, bazı testler yapsanız bile, denemeden API'nızla bağlantı kuracağınızı garanti edemezsiniz.
Yine de yapmaya çalıştığınız işlemi deneyin. Başarısız olursa, python size bildirmek için bir istisna atmalıdır.
Bir bağlantı tespit etmek için önce bazı önemsiz işlemleri denemek için bir yarış durumu getirecektir. Test ettiğinizde internet bağlantısı geçerliyse, ancak gerçek bir iş yapmanız gerekmeden önce kapanırsa ne olur?
Localhost olarak değiştirildi, bu işe yaramayabilir 127.0.0.1
Try
import socket
ipaddress=socket.gethostbyname(socket.gethostname())
if ipaddress=="127.0.0.1":
print("You are not connected to the internet!")
else:
print("You are connected to the internet with the IP address of "+ ipaddress )
Düzenlenmedikçe, internete bağlı olmadığınızda bilgisayarlarınızın IP'si 127.0.0.1 olacaktır. Bu kod temel olarak IP adresini alır ve ardından yerel ana bilgisayar IP adresi olup olmadığını sorar. umarım yardımcı olur
İşte benim versiyonum
import requests
try:
if requests.get('https://google.com').ok:
print("You're Online")
except:
print("You're Offline")
Aşağıdakileri içeren modern bir taşınabilir çözüm requests
:
import requests
def internet():
"""Detect an internet connection."""
connection = None
try:
r = requests.get("https://google.com")
r.raise_for_status()
print("Internet connection detected.")
connection = True
except:
print("Internet connection not detected.")
connection = False
finally:
return connection
Veya istisna oluşturan bir sürüm:
import requests
from requests.exceptions import ConnectionError
def internet():
"""Detect an internet connection."""
try:
r = requests.get("https://google.com")
r.raise_for_status()
print("Internet connection detected.")
except ConnectionError as e:
print("Internet connection not detected.")
raise e
Bunu yapmanın en iyi yolu, web sitesini bulamazsa python'un her zaman verdiği bir IP adresine karşı kontrol etmektir. Bu durumda bu benim kodum:
import socket
print("website connection checker")
while True:
website = input("please input website: ")
print("")
print(socket.gethostbyname(website))
if socket.gethostbyname(website) == "92.242.140.2":
print("Website could be experiencing an issue/Doesn't exist")
else:
socket.gethostbyname(website)
print("Website is operational!")
print("")
en sevdiğim, bir kümede komut dosyası çalıştırıp çalıştırmadığınızda
import subprocess
def online(timeout):
try:
return subprocess.run(
['wget', '-q', '--spider', 'google.com'],
timeout=timeout
).returncode == 0
except subprocess.TimeoutExpired:
return False
Bu, hiçbir şeyi indirmeden değil, verilen uzak dosyanın web'de var olup olmadığını kontrol ederek sessizce çalışır
Alarak unutbu cevabını bir başlangıç noktası olarak, ve, basit bir sınıf yaptık değişen bir "statik" IP adresine göre geçmişte yakılmış olan bu çekler "yani URL'yi kullanarak (DNS aramasını kullanarak kez https: // www .google.com ") ve ardından yanıt veren sunucunun IP adresini sonraki denetimlerde kullanmak üzere saklar. Bu şekilde, IP adresi her zaman günceldir (sınıfın en az birkaç yılda bir yeniden başlatıldığı varsayılarak). Ayrıca , sunucunun IP adresini (yeniden yönlendirme vb. Sonra) nasıl alacağımı gösteren bu cevap için gawry'ye kredi veriyorum . Lütfen bu çözümün görünür hileliğini göz ardı edin, burada minimal bir çalışma örneği alacağım. :)
İşte ne var:
import socket
try:
from urllib2 import urlopen, URLError
from urlparse import urlparse
except ImportError: # Python 3
from urllib.parse import urlparse
from urllib.request import urlopen, URLError
class InternetChecker(object):
conn_url = 'https://www.google.com/'
def __init__(self):
pass
def test_internet(self):
try:
data = urlopen(self.conn_url, timeout=5)
except URLError:
return False
try:
host = data.fp._sock.fp._sock.getpeername()
except AttributeError: # Python 3
host = data.fp.raw._sock.getpeername()
# Ensure conn_url is an IPv4 address otherwise future queries will fail
self.conn_url = 'http://' + (host[0] if len(host) == 2 else
socket.gethostbyname(urlparse(data.geturl()).hostname))
return True
# Usage example
checker = InternetChecker()
checker.test_internet()
Six'in cevabını almak, yeni teknikler konusunda yeni gelenlerin kaybolması nedeniyle önemli bir konuyu basitleştirebileceğimizi düşünüyorum.
Burada nihayet PV izleme için günde bir kez bağlantımın (3G, yavaş) kurulmasını beklerken kullanacağım.
Raspbian 3.4.2 ile Pyth3 altında çalışır
from urllib.request import urlopen
from time import sleep
urltotest=http://www.lsdx.eu # my own web page
nboftrials=0
answer='NO'
while answer=='NO' and nboftrials<10:
try:
urlopen(urltotest)
answer='YES'
except:
essai='NO'
nboftrials+=1
sleep(30)
maksimum koşu: 5 dakika ulaştı eğer bir saat içinde deneyeceğim ama onun komut dosyası biraz daha!
Alarak Ivelin yanıtını ve benim yönlendirici onun ip adresi 192.168.0.1 sunar ve hiçbir internet bağlantısı sorgulama google.com varsa kafa döndürür gibi bazı ekstra kontrol ekleyin.
import socket
def haveInternet():
try:
# first check if we get the correct IP-Address or just the router's IP-Address
info = socket.getaddrinfo("www.google.com", None)[0]
ipAddr = info[4][0]
if ipAddr == "192.168.0.1" :
return False
except:
return False
conn = httplib.HTTPConnection("www.google.com", timeout=5)
try:
conn.request("HEAD", "/")
conn.close()
return True
except:
conn.close()
return False
Bu benim için Python'da çalışıyor3.6
import urllib
from urllib.request import urlopen
def is_internet():
"""
Query internet using python
:return:
"""
try:
urlopen('https://www.google.com', timeout=1)
return True
except urllib.error.URLError as Error:
print(Error)
return False
if is_internet():
print("Internet is active")
else:
print("Internet disconnected")
Joel'in koduna birkaç tane ekledim.
import socket,time
mem1 = 0
while True:
try:
host = socket.gethostbyname("www.google.com") #Change to personal choice of site
s = socket.create_connection((host, 80), 2)
s.close()
mem2 = 1
if (mem2 == mem1):
pass #Add commands to be executed on every check
else:
mem1 = mem2
print ("Internet is working") #Will be executed on state change
except Exception as e:
mem2 = 0
if (mem2 == mem1):
pass
else:
mem1 = mem2
print ("Internet is down")
time.sleep(10) #timeInterval for checking
Projelerim için google genel DNS sunucusuna 8.8.8.8 ping atmak için değiştirilmiş komut dosyası kullanıyorum . Harici bağımlılığı olmayan 1 saniyelik zaman aşımı ve çekirdek python kitaplıkları kullanma:
import struct
import socket
import select
def send_one_ping(to='8.8.8.8'):
ping_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp'))
checksum = 49410
header = struct.pack('!BBHHH', 8, 0, checksum, 0x123, 1)
data = b'BCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwx'
header = struct.pack(
'!BBHHH', 8, 0, checksum, 0x123, 1
)
packet = header + data
ping_socket.sendto(packet, (to, 1))
inputready, _, _ = select.select([ping_socket], [], [], 1.0)
if inputready == []:
raise Exception('No internet') ## or return False
_, address = ping_socket.recvfrom(2048)
print(address) ## or return True
send_one_ping()
Select zaman aşımı değeri 1'dir, ancak bu örnekte 1 saniyeden daha kolay başarısız seçim de ondalık sayı olabilir.
istekleri içe aktarın ve bu basit python kodunu deneyin.
def check_internet():
url = 'http://www.google.com/'
timeout = 5
try:
_ = requests.get(url, timeout=timeout)
return True
except requests.ConnectionError:
return False