กำลังตรวจสอบการเชื่อมต่อเครือข่าย


141

ฉันต้องการดูว่าฉันสามารถเข้าถึง API ออนไลน์ได้หรือไม่ แต่ฉันต้องเข้าถึงอินเทอร์เน็ตได้

ฉันจะดูได้อย่างไรว่ามีการเชื่อมต่อและใช้งานได้โดยใช้ Python


หากคุณอยู่ใน python มันจะทำให้เกิดข้อยกเว้นในกรณีที่การเชื่อมต่อล้มเหลวหรือหมดเวลา คุณสามารถลอง / จับสิ่งนั้นหรือปล่อยให้มันปรากฏขึ้นก็ได้
jdizzle

1
@Triptych: ฉันหวังว่ามันจะเป็นเรื่องตลกเพราะมันไม่ได้ผล
inspectorG4dget

1
@ inspectorG4dget:easy_install system_of_tubes
S.Lott

2
@aF: ดูวิธีแก้ปัญหาของ Unutbu จะแสดง (ด้วยวิธีที่เร็วที่สุด) วิธีตรวจสอบว่าคุณสามารถเข้าถึง google.com ได้หรือไม่ หากปัญหาของคุณเกี่ยวข้องกับการเข้าถึง API ทำไมไม่ลองเข้าถึงโดยตั้งค่า timeout = 1 ซึ่งจะบอกคุณได้อย่างชัดเจนว่า API ที่คุณต้องการเข้าถึงสามารถเข้าถึงได้หรือไม่ เมื่อคุณทราบแล้วคุณสามารถดำเนินการต่อและเข้าถึง API หรือรอสักครู่เมื่อคุณสามารถเข้าถึงได้
inspectorG4dget

อย่างที่บอกฉันแค่ต้องการสิ่งง่ายๆอย่างที่ unutbu พูด คุณไม่จำเป็นต้องวุ่นวายกับเรื่องนี้ ..
aF.

คำตอบ:


136

บางทีคุณอาจใช้สิ่งนี้:

import urllib2

def internet_on():
    try:
        urllib2.urlopen('http://216.58.192.142', timeout=1)
        return True
    except urllib2.URLError as err: 
        return False

ปัจจุบัน 216.58.192.142 เป็นหนึ่งในที่อยู่ IP สำหรับ google.com เปลี่ยนhttp://216.58.192.142เพื่อสิ่งที่เว็บไซต์คาดว่าจะสามารถตอบสนองอย่างรวดเร็ว

IP คงที่นี้จะไม่จับคู่กับ google.com ตลอดไป ดังนั้นรหัสนี้จึงไม่แข็งแรง - จำเป็นต้องมีการบำรุงรักษาอย่างต่อเนื่องเพื่อให้ใช้งานได้

สาเหตุที่โค้ดด้านบนใช้ที่อยู่ IP แบบคงที่แทนชื่อโดเมนแบบเต็ม (FQDN) เนื่องจาก FQDN ต้องการการค้นหา DNS เมื่อเครื่องไม่มีการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานได้การค้นหา DNS เองอาจบล็อกการโทรไปurllib_request.urlopenนานกว่าหนึ่งวินาที ขอบคุณ @rzetterberg ที่ชี้ให้เห็นสิ่งนี้


หากที่อยู่ IP คงที่ด้านบนไม่ทำงานคุณสามารถค้นหาที่อยู่ IP ปัจจุบันสำหรับ google.com (บน unix) ได้โดยเรียกใช้

% dig google.com  +trace 
...
google.com.     300 IN  A   216.58.192.142

1
เพียงหมายเหตุเกี่ยวกับ "การโทรurlopenจะใช้เวลาไม่นานเกิน 1 วินาทีแม้ว่าอินเทอร์เน็ตจะไม่" เปิด "ก็ตาม - คำพูด สิ่งนี้ไม่เป็นความจริงหาก url ที่ให้มาไม่ถูกต้องการค้นหา DNS จะบล็อก เป็นจริงสำหรับการเชื่อมต่อกับเว็บเซิร์ฟเวอร์จริงเท่านั้น วิธีที่ง่ายที่สุดในการหลีกเลี่ยงบล็อกการค้นหา DNS นี้คือใช้ที่อยู่ IP แทนจากนั้นรับประกันว่าจะใช้เวลาเพียง 1 วินาที :)
rzetterberg

8
ไม่ทำงานอีกต่อไป เมื่อวันที่กันยายน 2013 74.125.113.99หมดเวลาหลังจากเวลาผ่านไปนานดังนั้นฟังก์ชันนี้จะคืนค่า False เสมอ ฉันคิดว่า Google ได้เปลี่ยนเครือข่ายของพวกเขาถูกตั้งค่า
theamk

4
ตอนนี้ส่วนที่เหลือเป็นเรื่องง่าย Google สำหรับ "74.125.113.99 urllib" จะส่งคืนโครงการโอเพ่นซอร์สหลายพันโครงการซึ่งรวมรหัสที่ไม่ถูกต้อง (สำหรับฉันแค่หน้าแรกมีอย่างน้อย 5: nvpy, sweekychebot, malteseDict, upy, checkConnection) ตอนนี้พวกเขาแตกสลายไปหมดแล้ว
theamk

4
หากไม่ชัดเจนฉันไม่แนะนำให้ใช้วิธีนี้ IP เก่าใช้ได้ไม่ถึง 3 ปี IP ใหม่ใช้งานได้แล้ววันนี้ ใส่ไว้ในโครงการของคุณและอาจพังลงอย่างลึกลับในเวลาไม่ถึง 3 ปี
theamk

2
เอ่อ ... แค่เปิดhttp://google.comแล้วคุณก็แก้ปัญหาที่ทุกคนพูดถึงที่นี่ ไม่จำเป็นต้องใช้ที่อยู่ IP ...
Jason C

112

หากเราสามารถเชื่อมต่อกับเซิร์ฟเวอร์อินเทอร์เน็ตได้แสดงว่าเรามีการเชื่อมต่ออย่างแน่นอน อย่างไรก็ตามเพื่อแนวทางที่รวดเร็วและน่าเชื่อถือที่สุดโซลูชันทั้งหมดควรเป็นไปตามข้อกำหนดต่อไปนี้อย่างน้อยที่สุด:

  • หลีกเลี่ยงการแก้ปัญหา DNS (เราจะต้องมี IP ที่เป็นที่รู้จักและรับประกันว่าจะพร้อมใช้งานเกือบตลอดเวลา)
  • หลีกเลี่ยงการเชื่อมต่อเลเยอร์แอปพลิเคชัน (เชื่อมต่อกับบริการ HTTP / FTP / IMAP)
  • หลีกเลี่ยงการเรียกใช้ยูทิลิตี้ภายนอกจาก Python หรือภาษาอื่น ๆ ที่เลือก (เราจำเป็นต้องสร้างโซลูชันที่ไม่เชื่อเรื่องพระเจ้าภาษาที่ไม่ต้องพึ่งพาโซลูชันของบุคคลที่สาม)

เพื่อให้เป็นไปตามนี้แนวทางหนึ่งคือตรวจสอบว่าเซิร์ฟเวอร์ DNS สาธารณะของ Googleสามารถเข้าถึงได้หรือไม่ ที่อยู่ IPv4 สำหรับเซิร์ฟเวอร์เหล่านี้คือ8.8.8.8และ8.8.4.4. เราสามารถลองเชื่อมต่อกับรายการใดก็ได้

Nmap ด่วนของโฮสต์8.8.8.8ให้ผลลัพธ์ด้านล่าง:

$ 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

อย่างที่เราเห็น53/tcpคือเปิดและไม่มีการกรอง หากคุณเป็นผู้ใช้ที่ไม่ใช่รูทอย่าลืมใช้sudoหรือ-Pnอาร์กิวเมนต์เพื่อให้ Nmap ส่งแพ็กเก็ตโพรบที่สร้างขึ้นมาและตรวจสอบว่ามีโฮสต์อยู่หรือไม่

ก่อนที่เราจะลองใช้ Python ลองทดสอบการเชื่อมต่อโดยใช้เครื่องมือภายนอก Netcat:

$ nc 8.8.8.8 53 -zv
Connection to 8.8.8.8 53 port [tcp/domain] succeeded!

ยืนยัน netcat ที่เราสามารถเข้าถึงมากกว่า8.8.8.8 53/tcpตอนนี้เราสามารถตั้งค่าการเชื่อมต่อซ็อกเก็ต8.8.8.8:53/tcpใน Python เพื่อตรวจสอบการเชื่อมต่อ:

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()

อีกวิธีหนึ่งคือการส่งโพรบ DNS ที่สร้างขึ้นเองไปยังเซิร์ฟเวอร์เหล่านี้และรอการตอบกลับ แต่ฉันคิดว่ามันอาจพิสูจน์ได้ช้ากว่าในการเปรียบเทียบเนื่องจากแพ็คเก็ตลดลงการแก้ปัญหา DNS ล้มเหลว ฯลฯ โปรดแสดงความคิดเห็นหากคุณคิดเป็นอย่างอื่น

อัปเดต # 1: ขอบคุณความคิดเห็นของ @ theamk การหมดเวลาเป็นอาร์กิวเมนต์และเริ่มต้น3sโดยค่าเริ่มต้น

อัปเดต # 2: ฉันทำการทดสอบอย่างรวดเร็วเพื่อระบุการใช้งานคำตอบที่ถูกต้องทั้งหมดสำหรับคำถามนี้โดยเร็วและทั่วไปที่สุด นี่คือสรุป:

$ 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

และอีกครั้ง:

$ 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ในผลลัพธ์ข้างต้นแสดงว่าการใช้งานทั้งหมดนี้จากผู้เขียนที่เกี่ยวข้องระบุการเชื่อมต่อกับอินเทอร์เน็ตได้อย่างถูกต้อง เวลาจะแสดงด้วยความละเอียดมิลลิวินาที

อัปเดต # 3: ทดสอบอีกครั้งหลังจากเปลี่ยนแปลงการจัดการข้อยกเว้น:

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

6
นี่คือคำตอบที่ดีที่สุดหลีกเลี่ยงการแก้ปัญหา DNS และแดกดันให้คำปรึกษาบริการ DNS ของ Google ที่พอร์ต 53
m3nda

1
@AviMehenwal Google ให้ IP นี้เป็นส่วนหนึ่งของบริการแก้ปัญหาชื่อ DNS ฟรี IP ไม่ควรเปลี่ยนแปลงเว้นแต่ Google จะตัดสินใจเป็นอย่างอื่น ฉันใช้มันเป็นเซิร์ฟเวอร์ DNS ทางเลือกมาหลายปีแล้วโดยไม่มีปัญหาใด ๆ
7 ชม

1
@ ลุคขอบคุณที่ชี้ให้เห็น ฉันได้อัปเดตคำตอบเพื่อแจ้งให้ผู้ใช้ทราบเกี่ยวกับข้อยกเว้นและส่งคืน False เป็นคำตอบเริ่มต้น
7h3r น.

2
@JasonC การเชื่อมต่อกับ TCP / 53 แตกต่างจากการเชื่อมต่อ DNS ผ่านพอร์ต 53 จากการเปรียบเทียบของคุณพอร์ต TCP ทุกพอร์ตที่ใช้โดยแอปพลิเคชันจะถูกจัดประเภทเป็นการเชื่อมต่อโปรโตคอลระดับแอปพลิเคชัน ไม่นั่นไม่จริง การเชื่อมต่อผ่านซ็อกเก็ต TCP ไปยังพอร์ตไม่ใช่การเชื่อมต่อระดับแอปพลิเคชัน ฉันไม่ได้ทำการค้นหา DNS แต่เป็นการจับมือแบบ TCP ครึ่งเดียว ไม่ใช่สิ่งเดียวกับการค้นหา DNS แบบเต็ม
7 ชม

2
เราไม่ควรเรียกclose()ซ็อกเก็ต?
brk

61

การสร้างคำขอ HEAD จะเร็วกว่าดังนั้นจึงไม่มีการดึง HTML
นอกจากนี้ฉันแน่ใจว่า Google ต้องการให้ดีกว่านี้ :)

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

8
ใช้เวลาเพียง 20 มิลลิวินาทีในขณะที่คำตอบสูงสุดใช้เวลา 1 วินาที
เก่ง

8
+1 ไม่มีเหตุผลที่จะดาวน์โหลดทั้งหน้าหากคุณต้องการตรวจสอบว่าเซิร์ฟเวอร์สามารถเข้าถึงได้และตอบสนองหรือไม่ ดาวน์โหลดเนื้อหาหากคุณต้องการเนื้อหา
thatsIch

ไม่ว่าด้วยเหตุผลใดการใช้ url '8.8' ยังคงใช้งานได้ซึ่งเห็นได้ชัดว่า '8.8' หรือ ' 8.8 ' ใช้ไม่ได้ในเว็บเบราว์เซอร์จริง
Polv

2 ชั่วโมงมองหาวิธีแก้ปัญหาที่ใช้งานได้แล้วฉันก็พบสิ่งนี้ ... สะอาดและเรียบง่าย
Pedro Serpa

21

เป็นทางเลือกอื่นสำหรับคำตอบของ ubutnu / Kevin C ฉันใช้requestsแพ็คเกจดังนี้:

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

โบนัส: สามารถขยายไปยังฟังก์ชันนี้ที่ส่ง Ping ไปยังเว็บไซต์ได้

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

1
ขอเป็นห้องสมุดที่ยอดเยี่ยม อย่างไรก็ตามไม่เหมือนกับตัวอย่างมากมายที่นี่ฉันจะใช้example.comหรือexample.org ของ IANA เป็นตัวเลือกระยะยาวที่น่าเชื่อถือกว่าเนื่องจากICANNควบคุมโดยสมบูรณ์
chirale

มีวิธีอื่นในการตรวจสอบสถานะการทำงานของอินเทอร์เน็ตหรือไม่ เพราะถ้าคุณเจาะgoogle.comซ้ำอีกครั้งมันจะบล็อก IP ของเรา มีวิธีอื่นไหม.?
Sanjiv

15

เพียงเพื่ออัปเดตสิ่งที่ unutbu กล่าวสำหรับโค้ดใหม่ใน Python 3.2

def check_connectivity(reference):
    try:
        urllib.request.urlopen(reference, timeout=1)
        return True
    except urllib.request.URLError:
        return False

และโปรดทราบว่าอินพุตที่นี่ (ข้อมูลอ้างอิง) คือ url ที่คุณต้องการตรวจสอบ: ฉันขอแนะนำให้เลือกสิ่งที่เชื่อมต่อได้อย่างรวดเร็วในที่ที่คุณอาศัยอยู่ - เช่นฉันอาศัยอยู่ในเกาหลีใต้ดังนั้นฉันอาจตั้งค่าการอ้างอิงเป็นhttp: / /www.naver.com .


ฉันจะรอ 30 วินาทีหากไม่มีเซิร์ฟเวอร์ DNS
Viktor Joras

10

คุณสามารถลองดาวน์โหลดข้อมูลและหากการเชื่อมต่อล้มเหลวคุณจะรู้ว่าบางครั้งการเชื่อมต่อไม่ดี

โดยทั่วไปคุณไม่สามารถตรวจสอบว่าคอมพิวเตอร์เชื่อมต่อกับอินเทอร์เน็ตหรือไม่ อาจมีสาเหตุหลายประการสำหรับความล้มเหลวเช่นการกำหนดค่า DNS ผิดไฟร์วอลล์ NAT ดังนั้นแม้ว่าคุณจะทำการทดสอบบางอย่างคุณก็ไม่สามารถรับประกันได้ว่าคุณจะเชื่อมต่อกับ API ของคุณได้จนกว่าคุณจะลอง


2
"ขอการให้อภัยง่ายกว่าการอนุญาต"
cobbal

สิ่งนี้ไม่จำเป็นต้องดีขนาดนั้น ฉันเพียงแค่ต้องพยายามเชื่อมต่อกับไซต์หรือ ping บางสิ่งบางอย่างและถ้ามันทำให้หมดเวลาvoilá ฉันจะทำเช่นนั้นได้อย่างไร?
เอฟ.

มีเหตุผลใดบ้างที่คุณไม่สามารถลองเชื่อมต่อกับ API ได้? ทำไมคุณต้องตรวจสอบก่อนเชื่อมต่อจริง?
Tomasz Wysocki

ฉันสร้างเพจ html โดยใช้ python หน้า html แยกข้อโต้แย้งที่ฉันให้ในโปรแกรม python ฉันต้องใส่โค้ด html บางส่วนเท่านั้นถ้าฉันสามารถเข้าถึง api ได้ นั่นเป็นเหตุผลที่ฉันต้องรู้มาก่อน
ก.

6
import urllib

def connected(host='http://google.com'):
    try:
        urllib.urlopen(host)
        return True
    except:
        return False

# test
print( 'connected' if connected() else 'no internet!' )

สำหรับ python 3 ให้ใช้ urllib.request.urlopen(host)


5

ลองดำเนินการที่คุณพยายามทำต่อไป หากล้มเหลว python ควรโยนข้อยกเว้นแจ้งให้คุณทราบ

หากต้องการลองใช้การดำเนินการเล็กน้อยก่อนเพื่อตรวจจับการเชื่อมต่อจะเป็นการแนะนำสภาวะการแข่งขัน จะเกิดอะไรขึ้นถ้าการเชื่อมต่ออินเทอร์เน็ตถูกต้องเมื่อคุณทดสอบ แต่หยุดทำงานก่อนที่คุณจะต้องทำงานจริง?


3

สิ่งนี้อาจใช้ไม่ได้หาก localhost ถูกเปลี่ยนจาก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 )

IP ของคอมพิวเตอร์ของคุณจะเป็น 127.0.0.1 เมื่อไม่ได้เชื่อมต่ออินเทอร์เน็ต โดยทั่วไปรหัสนี้จะได้รับที่อยู่ IP จากนั้นถามว่าเป็นที่อยู่ IP ของ localhost หรือไม่ หวังว่าจะช่วยได้


นี่เป็นการตรวจสอบที่น่าสนใจแม้ว่าจะระบุได้ว่าคุณเชื่อมต่อกับเครือข่ายเท่านั้น ไม่ว่าจะเป็นอินเทอร์เน็ตหรือเครือข่ายย่อย NAT ก็ยังคงเป็นคำถาม
7h3r น

@ 7h3rAm นั่นเป็นจุดที่ดี DCHP ไม่ต้องการการเชื่อมต่ออินเทอร์เน็ตความผิดพลาดของฉัน

สิ่งนี้ต้องการการเชื่อมต่อ NIC ของเครือข่ายที่ได้รับการกำหนด IP แตกต่างจากคำตอบอื่น ๆ ทั้งหมดไม่จำเป็นต้องเชื่อมต่อกับ LAN, เราเตอร์, ไฟร์วอลล์, ISP ไปจนถึงระบบอื่น ยังไม่สามารถแสดงว่า NIC เชื่อมต่ออยู่หากเป็นที่อยู่ที่ไม่ได้กำหนด DHCP (คงที่)
user150471

@ user150471 ชี้แล้วขอบคุณที่อุดหนุน

3

นี่คือเวอร์ชันของฉัน

import requests

try:
    if requests.get('https://google.com').ok:
        print("You're Online")
except:
    print("You're Offline")

1
ฉันชอบอันนี้ แต่จะดีกว่าถ้ายกเว้น Timeout เฉพาะหรือข้อผิดพลาดในการเชื่อมต่อที่เกิดขึ้นจากคำขอ ตามที่เป็นอยู่ Ctrl-C ที่รวดเร็วทันใจจะพิมพ์แบบออฟไลน์
user2561747

2

โซลูชันแบบพกพาที่ทันสมัยพร้อมด้วย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

หรือเวอร์ชันที่มีข้อยกเว้น:

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

1

วิธีที่ดีที่สุดคือตรวจสอบกับที่อยู่ IP ที่ python ให้ไว้เสมอหากไม่พบเว็บไซต์ ในกรณีนี้นี่คือรหัสของฉัน:

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("")

1

สิ่งที่ฉันชอบเมื่อเรียกใช้สคริปต์บนคลัสเตอร์หรือไม่

import subprocess

def online(timeout):
    try:
        return subprocess.run(
            ['wget', '-q', '--spider', 'google.com'],
            timeout=timeout
        ).returncode == 0
    except subprocess.TimeoutExpired:
        return False

สิ่งนี้ทำงานอย่างเงียบ ๆ ไม่ดาวน์โหลดอะไรเลยนอกจากตรวจสอบว่ามีไฟล์ระยะไกลที่ระบุอยู่บนเว็บ


0

การใช้คำตอบของ unutbuเป็นจุดเริ่มต้นและในอดีตเคยถูกเบิร์นโดยการเปลี่ยนที่อยู่ IP "คงที่" ฉันได้สร้างคลาสง่ายๆที่ตรวจสอบครั้งเดียวโดยใช้การค้นหา DNS (เช่นใช้ URL " https: // www .google.com ") แล้วจัดเก็บที่อยู่ IP ของเซิร์ฟเวอร์ที่ตอบสนองเพื่อใช้ในการตรวจสอบในภายหลัง ด้วยวิธีนี้ที่อยู่ IP จะเป็นปัจจุบันอยู่เสมอ (โดยสมมติว่าคลาสนั้นได้รับการเริ่มต้นใหม่อย่างน้อยหนึ่งครั้งในทุกๆสองสามปี) ฉันยังให้เครดิตกับ gawry สำหรับคำตอบนี้ซึ่งแสดงวิธีรับที่อยู่ IP ของเซิร์ฟเวอร์ (หลังจากการเปลี่ยนเส้นทาง ฯลฯ ) โปรดอย่ามองข้ามความแฮ็กที่ชัดเจนของโซลูชันนี้ฉันจะดูตัวอย่างการทำงานขั้นต่ำที่นี่ :)

นี่คือสิ่งที่ฉันมี:

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()

0

การตอบคำถามหกข้อฉันคิดว่าเราสามารถทำให้ง่ายขึ้นได้ปัญหาที่สำคัญเนื่องจากผู้มาใหม่จะหลงทางในเรื่องทางเทคนิคขั้นสูง

ต่อไปนี้คือสิ่งที่ฉันจะใช้เพื่อรอการเชื่อมต่อ (3G ช้า) วันละครั้งสำหรับการตรวจสอบ PV ของฉัน

ทำงานภายใต้ Pyth3 กับ Raspbian 3.4.2

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)       

วิ่งสูงสุด: 5 นาทีหากไปถึงฉันจะพยายามในเวลาหนึ่งชั่วโมง แต่เป็นสคริปต์อีกเล็กน้อย!


Essai var ของคุณไม่ได้ใช้งานใช่หรือไม่?
kidCoder

0

การตอบ Ivelin ของและเพิ่มบางตรวจสอบเป็นพิเศษเราเตอร์ของฉันให้อยู่ IP 192.168.0.1 และส่งกลับหัวถ้ามีการเชื่อมต่ออินเทอร์เน็ตไม่เมื่อสอบถาม google.com

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

0

สิ่งนี้ใช้ได้กับฉันใน Python3.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")

0

ฉันเพิ่มรหัสของ Joel ไปเล็กน้อย

    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

0

สำหรับโครงการของฉันฉันใช้สคริปต์ที่แก้ไขเพื่อ ping เซิร์ฟเวอร์ DNS สาธารณะของ Google 8.8.8.8 ใช้การหมดเวลา 1 วินาทีและไลบรารี python หลักโดยไม่มีการอ้างอิงภายนอก:

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()

เลือกค่าการหมดเวลาเป็น 1 แต่สามารถเป็นจำนวนจุดลอยของทางเลือกที่จะล้มเหลวมากขึ้นอย่างรวดเร็วกว่า 1 วินาทีในตัวอย่างนี้


0

ตรวจสอบให้แน่ใจว่า pip ของคุณทันสมัยโดยการเรียกใช้

pip install --upgrade pip

ติดตั้งแพ็คเกจการร้องขอโดยใช้

pip install requests  
    import requests
    import webbrowser
    url = "http://www.youtube.com"

    timeout = 6
    try:
        request = requests.get(url, timeout=timeout)
        print("Connected to the Internet")
        print("browser is loading url")
        webbrowser.open(url)
    except (requests.ConnectionError, requests.Timeout) as exception:
       print("poor or no internet connection.")

0

คำขอนำเข้าและลองใช้รหัส python แบบธรรมดานี้

def check_internet():
    url = 'http://www.google.com/'
    timeout = 5
    try:
        _ = requests.get(url, timeout=timeout)
        return True
    except requests.ConnectionError:
        return False

รหัสนี้จะถือว่าคุณมีการเชื่อมต่อกับอินเทอร์เน็ตและ DNS ของคุณมีการตอบสนอง
Thomas Johannesmeyer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.