亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(四):域名系統(tǒng)

 更新時間:2014年06月09日 21:58:28   作者:  
當(dāng)我們在上網(wǎng)的時候,通常輸入的是網(wǎng)址,其實(shí)這就是一個域名,而我們計(jì)算機(jī)網(wǎng)絡(luò)上的計(jì)算機(jī)彼此之間只能用IP地址才能相互識別

一、什么是域名系統(tǒng)

DNS 計(jì)算機(jī)域名系統(tǒng) (DNS) 是由解析器以及域名服務(wù)器組成的。當(dāng)我們在上網(wǎng)的時候,通常輸入的是網(wǎng)址,其實(shí)這就是一個域名,而我們計(jì)算機(jī)網(wǎng)絡(luò)上的計(jì)算機(jī)彼此之間只能用IP地址才能相互識別。再如,我們?nèi)ヒ籛EB服務(wù)器中請求一WEB頁面,我們可以在瀏覽器中輸入網(wǎng)址或者是相應(yīng)的IP地址,例如我們要上新浪網(wǎng),我們可以在IE的地址欄中輸入網(wǎng)址,也可輸入IP地址,但是這樣子的IP地址我們記不住或說是很難記住,所以有了域名的說法,這樣的域名會讓我們?nèi)菀椎挠涀 ?br>

名稱

含義

特性

域名服務(wù)器

保存有該網(wǎng)絡(luò)中所有主機(jī)的域名和對應(yīng)IP地址,并具有將域名轉(zhuǎn)換為IP地址功能的服務(wù)器。

域名必須對應(yīng)一個IP地址,而IP地址不一定只對應(yīng)一個域名,采用類似目錄樹的等級結(jié)構(gòu)。

域名解析服務(wù)器

域名與IP地址之間的轉(zhuǎn)換工作

域名解析過程中的查詢順序?yàn)椋罕镜鼐彺嬗涗?、區(qū)域記錄、轉(zhuǎn)發(fā)域名服務(wù)器、根域名服務(wù)器。 



二、訪問DNS的方法一:使用socket模塊
 
1、DNS查詢

以查詢www.external.example.com為例。首先,程序會和操作系統(tǒng)配置文件指定的本地名稱服務(wù)器通信。這個服務(wù)器是一個遞歸的名稱服務(wù)器,它收到請求并以適當(dāng)?shù)姆绞絺鬟f下去。遞歸服務(wù)器做的第一件事情是詢問.com域,回答是以一種指向另外一外名稱服務(wù)器的提名形式給出的。這個名稱服務(wù)器可以提供名稱中包含.com的信息。查詢發(fā)送到該服務(wù)器后,該服務(wù)器將以另一個提名回答進(jìn)行回應(yīng),指向另外一臺服務(wù)器,而這個服務(wù)器可以提供example.com的名稱信息。這個循環(huán)重復(fù)多次,直到查詢到external.example.com服務(wù)的名稱服務(wù)器。

2、正向查詢

最基本的查詢是正向查詢,即根據(jù)一個主機(jī)名來查找ip地址。Socket庫可以實(shí)現(xiàn)這種查詢,主要用函數(shù)socket.getaddrinfo()。注意,該函數(shù)和ipv6不兼容。

Getaddrinfo(host,port[,family[,sockettype[,proto[,flags]]]])

參數(shù)host為域名,以字符串形式給出代表一個IPV4/IPV6地址或者None.  
參數(shù)port如果字符串形式就代表一個服務(wù)名,比如“http”"ftp""email"等,或者為數(shù)字,或者為None  
參數(shù)family為地主族,可以為AF_INET  ,AF_INET6 ,AF_UNIX.  
參數(shù)socketype可以為SOCK_STREAM(TCP)或者SOCK_DGRAM(UDP)  
參數(shù)proto通常為0可以直接忽略  
參數(shù)flags為AI_*的組合,比如AI_NUMERICHOST,它會影響函數(shù)的返回值 

該函數(shù)返回值是一列tuple,每一個tuple如下:

(family,socktype,proto,canonname,sockaddr)

其中sockaddr實(shí)際上就是遠(yuǎn)程機(jī)器的地址和端口,也就是查詢的數(shù)據(jù)。

例如:

>>> import socket
>>> print socket.getaddrinfo('www.baidu.com',None)
[(2, 0, 0, '', ('61.135.169.125', 0)), (2, 0, 0, '', ('61.135.169.105', 0))]
>>> print socket.getaddrinfo('www.baidu.com',None)[0][4][0]
61.135.169.125
>>> print socket.getaddrinfo('www.baidu.com',None)[0][4][1]
0

注意:因?yàn)橐粋€網(wǎng)站可能有多個網(wǎng)址,所以兩次查詢時,結(jié)果不同也是很正常的。這里用一段代碼將所有查詢結(jié)果列出:

復(fù)制代碼 代碼如下:

##@小五義
import socket
host=raw_input('host:')
result=socket.getaddrinfo(host,None)
counter=0
for i in result:
   print "%-2d:%s"%(counter,i[4])
   counter+=1

運(yùn)行結(jié)果如下:

>>>
host:www.baidu.com
0 :('61.135.169.105', 0)
1 :('61.135.169.125', 0)
>>>
host:www.yahoo.com
0 :('106.10.170.118', 0)
>>>
host:www.163.com
0 :('60.210.18.169', 0)
1 :('123.132.254.15', 0)
3、反向查詢
反向查詢是指通過ip地址查詢域名。這里用到gethostbyaddr
gethostbyaddr(addr,len,type)
參數(shù)addr可以為IPv4或IPv6的IP地址,參數(shù)len為參數(shù)addr的長度,參數(shù)type為AF_INET。

下面給出的例子,將反向查詢ip地址的域名。

復(fù)制代碼 代碼如下:

##@小五義
import socket
hostip=raw_input('ip:')
try:
    result=socket.gethostbyaddr(hostip)
    print "hostname:"+result[0]
    print "\n Addresses:"
    for i in result[2]:
        print " " +i
except socket.herror, e:
    print "counld not look up name:",e

運(yùn)行結(jié)果是:

>>>

ip:127.0.0.1

hostname:localhost

 Addresses:

 127.0.0.1

>>>

ip:216.109.118.73

hostname:gi-2-19.bas1-1-con.ac2.yahoo.com

 Addresses:

 216.109.118.73

>>>

ip:123.132.254.15

counld not look up name: [Errno 11004] host not found

>>>

ip:60.210.18.169

counld not look up name: [Errno 11004] host not found

從運(yùn)行的結(jié)果看,第一次查詢到的兩個ip放進(jìn)去,卻反向查詢不到域名,這里我也沒搞明白是什么原因,有待高手解答。

三、訪問DNS的方法二:使用PyDNS進(jìn)行高級查詢

pyDNS提供了一個功能更強(qiáng)的訪問DNS系統(tǒng)的接口。其下載地址為http://pydns.sourceforge.net。其中py3dns是針對python3.x的,本人的學(xué)習(xí)環(huán)境是python2.6,所以就下載安裝了pydns。下載后解壓,將DNS文件夾拷貝到Python安裝文件夾下的Lib\site-packages\文件夾下即可。

1、簡單的pyDNS查詢

首先調(diào)用DNS.DiscoverNameServers()查找系統(tǒng)中的名稱服務(wù)器。然后建立一個請求對象DNS.Request()。DNS.Request()的req()方法用來執(zhí)行實(shí)際的查詢。通常有兩個參數(shù):name給出了實(shí)際查詢的名稱;qtype指定了record類型。當(dāng)使用請求對象來發(fā)出查詢請求時,pyDNS會返回一個包含結(jié)果的應(yīng)答對象(answer object),該對象有個屬性叫answers,包含所有返回的應(yīng)答列表。

在給出例子前,首先列出大多數(shù)的DNS records列表如下:
A Address. 網(wǎng)址記錄(定在右邊), 定義於 RFC 1035.  
AAAA  IPv6 Address. (第 6 代網(wǎng)址表式法). 定義於 RFC 1886.  
AFSDB  AFS Data Dase location. 定義於 RFC 1183.  
CNAME  Canonical Name (正式名稱), 定義於 RFC 1035. 這是定別名(alias)的指標(biāo)用法. 別名設(shè)定在 LHS, 正式名稱設(shè)定在 RHS.  
GPOS  Geographic POSition (地理位置)?, 定義於 RFC 1712. 過時(obsolete)用法, 不建議使用. . 
HINFO  Host INFOrmation (機(jī)器基本資料; OS, 硬體, ...), 定義於 RFC 1035.  
ISDN  ISDN (整合數(shù)位網(wǎng)路網(wǎng)址表示法), 定義於 RFC 1183.  
KEY  publick key (公開金匙; DNS 資料, 透過編碼, 密碼通訊), 定義於 RFC 2065.  
LOC  LOCation (網(wǎng)路所在的地理區(qū)域; 表經(jīng)緯度), 定於 RFC 1876.  
MB  MailBox. (信箱; 已經(jīng)很少使用), 定義於 RFC 1035. --> 參考 MX 記錄項(xiàng)目.  
MD  定義於 RFC 1035. 過時(obsolete)用法, 不建議使用. --> 參考 MX 記錄項(xiàng)目.  
MF  定義於 RFC 1035. 過時(obsolete)用法, 不建議使用. --> 參考 MX 記錄項(xiàng)目.  
MG  定義於 RFC 1035.  
MINFO  定義於 RFC 1035.  
MR  定義於 RFC 1035.  
MX  Mail eXchanger. (電子郵件, 交寄設(shè)定). 定義於 RFC 1035. 基本用法是, 當(dāng)一個 email address 包含某一筆 MX 記錄的 LHS時, 那麼 email 傳遞系統(tǒng)會, 將該電子郵件, 轉(zhuǎn)交給該筆 MX 的 RHS 所指示的系統(tǒng), 去進(jìn)一步處理.  
NULL  空記錄 ( 如空白行等; 無實(shí)際用途), 定義於 RFC 1035.  
NS  Name Server (表示 RHS 為一領(lǐng)域名稱伺服機(jī)器), 定義於 RFC 1035.  
NSAP  Network Services Access Point address. ( ISO-OSI 的網(wǎng)路服務(wù), 網(wǎng)址表示法) 定義於 RFC 1348, 另外又分別經(jīng)過 RFC 1637, 1706 兩次重新定義. 
NSAP-PTR  定義於 RFC 1348. 過時用法.  
NXT  定義於 RFC 2065.  
PTR  PoinTeR. ( 指標(biāo) ), 定義於 RFC 1035. 通常用於將 IP addr. 只回到某一個對應(yīng) 的 domain name. 

下面是一個簡單的例子:

復(fù)制代碼 代碼如下:

##@小五義
# -*- coding: cp936 -*-
import DNS
query=raw_input('輸入DNS:')
DNS.DiscoverNameServers()

reqobj=DNS.Request()
answerobj=reqobj.req(name=query,qtype=DNS.Type.ANY)
if not len(answerobj.answers):
    print "Not found"
for i in answerobj.answers:
  print "%-5s %s"%(i['typename'],i['data'])

運(yùn)行結(jié)果:

輸入DNS:163.com

TXT   ['v=spf1 include:spf.163.com -all']
A     123.58.180.8
A     123.58.180.5
A     123.58.180.6
A     123.58.180.7
MX    (10, '163mx03.mxmail.netease.com')
MX    (50, '163mx00.mxmail.netease.com')
MX    (10, '163mx01.mxmail.netease.com')
MX    (10, '163mx02.mxmail.netease.com')
NS    ns2.nease.net
NS    ns4.nease.net
NS    ns3.nease.net
NS    ns1.nease.net
輸入DNS:www.yahoo.com
CNAME fd-fp3.wg1.b.yahoo.com

2、查詢特殊的名稱服務(wù)器

前面的例子中,對ANY類型的查詢,有種特殊情況,就是如果不事先請求,有時候MX records會丟失。因此,正常情況下,不會使用ANY。解決方法是跳過本地名稱服務(wù)器,直接向該域中權(quán)威的名稱服務(wù)器發(fā)送查詢。為了這么做,需要使用系統(tǒng)默認(rèn)的名稱服務(wù)器來查找權(quán)威名稱服務(wù)器。這是通過查找接近于當(dāng)前域的NS records來實(shí)現(xiàn)的。下面的例子:

復(fù)制代碼 代碼如下:

##@小五義
# -*- coding: cp936 -*-
import DNS
def hierquery(qstring,qtype):
    reqobj=DNS.Request()
    try:
        print query
        answerobj=reqobj.req(name=query,qtype=qtype)
        answers=[x['data'] for x in answerobj.answers if x['type']==qtype]
        print answers
    except DNS.Base.DNSError:
        answers=[]
    if len(answers):
        return answers
    else:
        remainder=qstring.split(".",1)
        if len(remainder)==1:
            return None
        else:
            return hierquery(remainder[1],qtype)
def findnameservers(hostname):
    return hierquery(hostname,DNS.Type.NS)
def getrecordsfromnameserver(qstring,qtype,nslist):
    for ns in nslist:
        reqobj=DNS.Request(server=ns)
        try:
            answers=reqobj.req(name=qstring,qtype=qtype).answers
            if len(answers):
                return answers
        except DNS.Base.DNSError:
            pass
    return []

def nslookup(qstring,qtype,verbose=1):
    nslist=findnameservers(qstring)
    if nslist==None:
        raise RuntimeError,'找不到服務(wù)器'
    if verbose:
        print "服務(wù)器:",",".join(nslist)
    return getrecordsfromnameserver(qstring,qtype, nslist)
if  __name__=='__main__':
    query=raw_input('輸入網(wǎng)站:')
    DNS.DiscoverNameServers()
    answers=nslookup(query,DNS.Type.ANY)
    if not len(answers):
        print "未找到!"
    for i in answers:
        print "%-5s %s"%(i['typename'],i['data'])

運(yùn)行結(jié)果如下:

輸入網(wǎng)站:163.com

服務(wù)器: ns3.nease.net,ns1.nease.net,ns2.nease.net,ns4.nease.net

A     123.58.180.8
A     123.58.180.5
A     123.58.180.6
A     123.58.180.7
MX    (10, '163mx02.mxmail.netease.com')
MX    (10, '163mx03.mxmail.netease.com')
MX    (50, '163mx00.mxmail.netease.com')
MX    (10, '163mx01.mxmail.netease.com')
TXT   ['v=spf1 include:spf.163.com -all']
NS    ns4.nease.net
NS    ns1.nease.net
NS    ns2.nease.net
NS    ns3.nease.net

SOA   ('ns4.nease.net', 'admin.nease.net', ('serial', 20014505), ('refresh ', 801, '13 minutes'), ('retry', 3600, '1 hours'), ('expire', 604800, '1 weeks'), ('minimum', 18000, '5 hours'))

輸入網(wǎng)站:baidu.com

服務(wù)器: dns.baidu.com,ns4.baidu.com,ns2.baidu.com,ns3.baidu.com

SOA   ('dns.baidu.com', 'sa.baidu.com', ('serial', 2012081509), ('refresh ', 300, '5 minutes'), ('retry', 300, '5 minutes'), ('expire', 2592000, '4 weeks'), ('minimum', 7200, '2 hours'))

TXT   ['v=spf1 ip4:61.135.163.0/24 ip4:220.181.50.0/24 ip4:220.181.18.241 ip4:61.208.132.13 ip4:220.181.27.29 ip4:202.108.22.171 ip4:61.135.162.0/24 ip4:220.181.5.0/24 ip4:123.125.66.0/24 ip4:61.135.168.0/24 a mx ptr ~all']

A     123.125.114.144
A     220.181.111.85
A     220.181.111.86
MX    (20, 'jpmx.baidu.com')
MX    (20, 'mx50.baidu.com')
MX    (10, 'mx.mailcdn.baidu.com')
MX    (20, 'mx1.baidu.com')
NS    ns4.baidu.com
NS    ns2.baidu.com
NS    ns3.baidu.com
NS    dns.baidu.com

3、分解查詢結(jié)果

有些records,特別是NS、PTR、CNAME返回的數(shù)據(jù)中包含另一個主機(jī)名。為了得到最終的ip,需要分解返回的信息。這里用下面的代碼來完成:

復(fù)制代碼 代碼如下:

##@小五義
import sys, DNS, re
def hierquery(qstring,qtype):
    reqobj=DNS.Request()
    try:
        answerobj=reqobj.req(name=query,qtype=qtype)
        answers=[x['data'] for x in answerobj.answers if x['type']==qtype]
    except DNS.Base.DNSError:
        answers=[]
    if len(answers):
        return answers
    else:
        remainder=qstring.split(".",1)
        if len(remainder)==1:
            return None
        else:
            return hierquery(remainder[1],qtype)
def findnameservers(hostname):
    return hierquery(hostname,DNS.Type.NS)
def getrecordsfromnameserver(qstring,qtype,nslist):
    for ns in nslist:
        reqobj=DNS.Request(server=ns)
        try:
            answers=reqobj.req(name=qstring,qtype=qtype).answers
            if len(answers):
                return answers
        except DNS.Base.DNSError:
            pass
    return []

def nslookup(qstring,qtype,verbose=1):
    print qstring
    nslist=findnameservers(qstring)
    print nslist
    if nslist==None:
        raise RuntimeError,'找不到服務(wù)器'
    if verbose:
        print "服務(wù)器:",",".join(nslist)
    return getrecordsfromnameserver(qstring,qtype, nslist)

def getreverse(query):
    """Given the query, returns an appropriate reverse lookup string
    under IN-ADDR.ARPA if query is an IP address; otherwise, returns None.
    This function is not IPv6-compatible."""
    if re.search('^/d+/./d+/./d+/./d+$', query):
        octets = query.split('.')
        octets.reverse()
        return '.'.join(octets) + '.IN-ADDR.ARPA'
    return None

def formatline(index, typename, descr, data):
    retval = "%-2s %-5s" % (index, typename)
    if isinstance(data,list):
        return retval
    else:

        data = data.replace("/n", "/n         ")
        if descr != None and len(descr):
            retval += " %-12s" % (descr + ":")
        return retval + " " + data

DNS.DiscoverNameServers()
query1=raw_input('輸入網(wǎng)站:')
queries = [(query1, DNS.Type.ANY)]
donequeries = []
descriptions = {'A': 'IP address',
                'TXT': 'Data',
                'PTR': 'Host name',
                'CNAME': 'Alias for',
                'NS': 'Name server'}

while len(queries):
    (query, qtype) = queries.pop(0)
    if query in donequeries:
        # Don't look up the same thing twice
        continue
    donequeries.append(query)
    print "-" * 77
    print "Results for %s (lookup type %s)" %(query, DNS.Type.typestr(qtype))
    print
    rev = getreverse(query)
    if rev:
        print "IP address given; doing reverse lookup using", rev
        query = rev

    answers = nslookup(query, qtype, verbose = 0)
    if not len(answers):
        print "Not found."

    count = 0
    for answer in answers:
        count += 1
        if answer['typename'] == 'MX':
            print formatline(count, answer['typename'],
                             'Mail server',
                             "%s, priority %d" % (answer['data'][1],
                                                  answer['data'][0]))
            queries.append((answer['data'][1], DNS.Type.A))
        elif answer['typename'] == 'SOA':
            data = "/n" + "/n".join([str(x) for x in answer['data']])
            ##print data
            print formatline(count, 'SOA', 'Start of authority', data)
        elif answer['typename'] in descriptions:
            ##print answer['data']
            print formatline(count, answer['typename'],
                             descriptions[answer['typename']], answer['data'])
        else:
            print formatline(count, answer['typename'], None,
                             str(answer['data']))
        if answer['typename'] in ['CNAME', 'PTR']:
            queries.append((answer['data'], DNS.Type.ANY))
        if answer['typename'] == 'NS':
            queries.append((answer['data'], DNS.Type.A))

本人在運(yùn)行時,總是報錯,沒找到原因,望高手指點(diǎn)。

相關(guān)文章

  • 查看Python依賴包及其版本號信息的方法

    查看Python依賴包及其版本號信息的方法

    今天小編就為大家分享一篇查看Python依賴包及其版本號信息的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python+OpenCV實(shí)現(xiàn)在圖像上繪制矩形

    Python+OpenCV實(shí)現(xiàn)在圖像上繪制矩形

    這篇文章主要介紹了如何利用Python和OpenCV實(shí)現(xiàn)在圖像上繪制任意大小的矩形,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2022-03-03
  • 淺談Python協(xié)程

    淺談Python協(xié)程

    這篇文章主要介紹了Python協(xié)程的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 關(guān)于Python 解決Python3.9 pandas.read_excel(‘xxx.xlsx‘)報錯的問題

    關(guān)于Python 解決Python3.9 pandas.read_excel(‘xxx.xlsx‘)報錯的問題

    這篇文章主要介紹了關(guān)于Python 解決Python3.9 pandas.read_excel(‘xxx.xlsx‘)報錯的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • ubuntu22.04將python源切換為清華源的方法

    ubuntu22.04將python源切換為清華源的方法

    在使用pip命令安裝python的一些庫時,由于默認(rèn)服務(wù)器在國外,因此下載需要很長時間,本文主要介紹了ubuntu22.04將python源切換為清華源的方法,感興趣的可以了解一下
    2023-12-12
  • python爬蟲爬取筆趣網(wǎng)小說網(wǎng)站過程圖解

    python爬蟲爬取筆趣網(wǎng)小說網(wǎng)站過程圖解

    這篇文章主要介紹了python爬蟲爬取筆趣網(wǎng)小說網(wǎng)站過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • python 30行代碼實(shí)現(xiàn)螞蟻森林自動偷能量

    python 30行代碼實(shí)現(xiàn)螞蟻森林自動偷能量

    這篇文章主要介紹了python 30行代碼實(shí)現(xiàn)螞蟻森林自動偷能量的方法,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • 在python中l(wèi)ogger setlevel沒有生效的解決

    在python中l(wèi)ogger setlevel沒有生效的解決

    今天小編就為大家分享一篇在python中l(wèi)ogger setlevel沒有生效的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • Conda環(huán)境導(dǎo)出與導(dǎo)入的實(shí)現(xiàn)

    Conda環(huán)境導(dǎo)出與導(dǎo)入的實(shí)現(xiàn)

    本文主要介紹了Conda環(huán)境導(dǎo)出與導(dǎo)入的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Python with標(biāo)簽使用方法解析

    Python with標(biāo)簽使用方法解析

    這篇文章主要介紹了Python with標(biāo)簽使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01

最新評論