Python爬蟲(七)
學習Python爬蟲過程中的心得體會以及知識點的整理,方便我自己查找,也希望可以和大家一起交流。
—— socket庫應用詳解 ——
一.socket庫的函數
-
gethostname():返回主機名。
-
gethostbyname():將host主機名轉換爲ipv4地址。
socket.gethostbyname(‘edu.aqniu.com’)
socket.gethostbyname(‘www.jd.com’)
結果如下圖:
-
gethostbyname_ex():功能擴展的gethostbyname函數,返回主機名、主機別名列表、主機IP地址列表。
socket.gethostbyname_ex(‘edu.aqniu.com’)
socket.gethostbyname_ex(‘www.jd.com’)
結果如下圖:
我們可以看到京東的結果和安全牛有不同,即京東在使用CDN,所以建議使用gethostbyname_ex()而非gethostbyname()函數,前者信息更全面,更容易發現目標是否使用了CDN等服務。——瞭解CDN服務信息點擊鏈接查看。
-
gethostbyaddr():通過ip地址,返回包括主機名的三元組:(hostname, aliaslist, ipaddrlist)。
socket.gethostbyaddr(“180.76.136.71”)
socket.gethostbyaddr(‘202.165.102.205’)
socket.gethostbyaddr(‘192.168.99.110’)
但是這個函數有個問題:
對於部分ip地址會報錯,原因可能是gethostbyaddr在輸入參數時ip地址,並沒有經過dns轉換,因此無法獲取域名等信息。所以對於一部分ip地址不會報錯,一部分會報錯:
這裏通過雅虎的ip地址就可以查到,因此建議使用於內網。 -
getservbyport():返回該端口號的服務名,僅限本機。
socket.getservbyport(80, ‘tcp’)
-
getservbyname():通過給定的服務名,協議名,返回該服務所在的端口號。
socket.getservbyname(‘http’, ‘tcp’)
-
getaddrinfo():返回一個包含5元組的list,用來獲得host的地址信息,兼容ipv4和ipv6,在gethostbyname()函數不能兼容的ipv6的時候,可以使用這個函數。
socket.getaddrinfo(‘edu.aqniu.com’,80)
socket.getaddrinfo(“www.baidu.com”,None)
-
socket(family, type):創建一個socket連接。
● family參數代表地址家族,可爲AF_INET或AF_UNIX。
●AF_INET家族包括Internet地址,AF_UNIX家族用於同一臺機器上的進程間通信。
●socket.AF_INET指的是IPv4,socket.AF_INET6指的是IPv6。
●type表示套接字類型,socket.SOCK_STREAM指的是TCP連接,socket.SOCK_DGRAM指的是UDP協議socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-
connect((host, port)):連接到遠程地址,注意括號內部是一個元組。
sock.connect((‘edu.aqniu.com’, 80))
[連接成功沒有提示]
-
gettimeout():返回socket超時時間,以秒計(float)。
socket.gettimeout()
-
settimeout(timeout):設置Socket超時時間,以秒計(float)
socket.settimeout(timeout)
二.socket庫的方法
-
connect(address):連接到一個address對應的遠程socket。
如果連接被中斷,這個方法會等待直到連接完成,或者會拋出socket.timeout錯誤(超時)。 -
accept():接受一個連接,但前提是socket必須已經綁定了一個地址,在等待連接。
在默認情況下,socket是阻塞式的,意思就是socket的方法的調用在任務完成之前是不會返回的。
調用accept方法時,socket會時入“waiting”狀態。客戶請求連接時,方法建立連接並返回服務器。accept方法返回一個含有兩個元素的元組(connection,address)。第一個元素connection是新的socket對象,服務器必須通過它與客戶通信;第二個元素address是客戶的Internet地址。 -
recv(bufsize):從socket接收數據,注意是byte類型,bufsize指定一次最多接收的數據大小。
buf = connection.recv(1024)
-
recvfrom(bufsize) ,與上一個recv(bufsize)方法的區別是返回值除了數據還有發送數據的地址,返回值是一個數據,地址對(data, address)。
recv = s.recvfrom(1024)
-
send(bytes):發送數據到socket,前提是已經連接到遠程socket,返回值是發送數據的量,檢查數據是否發送完是應用的責任。
str = ‘Thank you for connecting’
str = str.encode()
connection.send(str) -
sendto(bytes, flags, address):基本與socket.send()相同。
s.sendto(str,client_addr)
-
close():關閉連接,當socket.close()執行時,與這個連接相關的底層操作也會關閉(如文件描述符),一旦關閉,再對相關的文件對象操作都會失敗。
connection.close()
-
bind(address):將socket對象綁定到一個地址,但這個地址必須是沒有被佔用的,否則會連接失敗。
這裏的address一般是一個ip,port對。s.bind(‘localhost’, 10000)
-
listen([backlog]) :監聽,使得服務器能接收服務端連接,如果backlog指定了(最少是0,如果比0小,系統默認改成0),限制可以連接的數量,如果沒有指定,將指派一個默認的合理值。
s.listen(5)