註:以下文章原文來自於Dr Charles Severance 的 《Python for Informatics》 本書中的許多例子關註的是讀取文件並查找數據,但在互聯網中還有許多不同信息源。 本章我們將偽裝成瀏覽器用超文本傳送協議(HTTP)從網站獲取網頁,通讀並分析它。 12.1 超文本傳送協 ...
註:以下文章原文來自於Dr Charles Severance 的 《Python for Informatics》
本書中的許多例子關註的是讀取文件並查找數據,但在互聯網中還有許多不同信息源。
本章我們將偽裝成瀏覽器用超文本傳送協議(HTTP)從網站獲取網頁,通讀並分析它。
12.1 超文本傳送協議-HTTP
支撐網頁運轉的網路協議實際非常簡單,在Python中內置了套接字(socket)模塊,使得使用套接字創建網路連接並獲取數據變得非常容易。
套接字最很像文件,可以對它進行讀寫,但它還提供在兩個程式間進行雙向連接。如果你向套接字寫信息,它將把信息發送另一端程式對應的套接字上,如果你讀取信息,你得到的將是對端程式發送的信息。
但是當你在對端未發送信息時去讀套接字,那麼你就只有坐乾等了。如果兩端的套接字都在接收數據而未發送數據,那麼它們將等上很長一段時間。
所以程式中用於互聯網通信的重要部分必須有某種協議。協議是一個定義誰先發、發的消息要乾什麼、怎麼響應這個消息、誰接著發等的準確規則的集合。在某種意義上,兩端應用程式好像在跳舞,並且確保不要踩到對方的腳趾上。
關於這些網路協議的文檔有很多,超文本傳送協議RFC2616鏈接如下:
http://www.w3.org/Protocols/rfc2616/rfc2616.txt
這個176頁又長又複雜的文檔有很多細節信息,如果你感興趣你可以通讀它。如果你翻看第36頁,你會發現GET請求的語法。你仔細閱讀,你會發現從一個網站請求獲取一個文檔,我們需要先和網站建立套接字連接,然後再發送GET請求。例如我們在80埠和www.py4inf.com伺服器建立連接,然後發送以下格式的請求:
GET http://www.py4inf.com/code/romeo.txt HTTP/1.0
其中第二個參數是我們請求的網頁,然後我們再發送一個空行。網頁伺服器將響應發送這個網頁的頭信息、文檔內容和一個緊跟其後的空行。
12.2 世界上最簡單的瀏覽器
也許顯示HTTP協議如何工作的最簡單方法就是寫一個非常簡單的Python程式,它將和網頁伺服器建立連接,並遵循HTTP協議規則,請求一個文檔,然後在伺服器送回後進行顯示。代碼如下:
import socket mysock = socket.socket(socket.AF_INET, socket.SOCKET_STREAM) mysock.connect(('www.py4inf.com', 80)) mysock.send(b'Get http://www.py4inf.com/code/romeo.txt HTTP/1.0\n\n') while True: data = mysock.recv(512).decode('utf-8') if (len(data) < 1): break print (data) mysock.close()
程式的輸出如下:
HTTP/1.1 200 OK
Date: Fri, 22 Apr 2016 15:21:42 GMT
Server: Apache
Last-Modified: Fri, 04 Dec 2015 19:05:04 GMT
ETag: "e103c2f4-a7-526172f5b5d89"
Accept-Ranges: bytes
Content-Length: 167
Cache-Control: max-age=604800, public
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: origin, x-requested-with, content-type
Access-Control-Allow-Methods: GET
Connection: close
Content-Type: text/plain
But soft what light through yonder window breaks
It is the east and Juliet is the sun
Arise fai
r sun and kill the envious moon
Who is already sick and pale with grief
輸出的開頭是網頁伺服器發送的描述這個文檔的頭信息。例如內容類型頭表示這個文檔時純文本文件(text/plain)。
在頭文件之後,伺服器發送了一個空行,表示頭文件結束。然後發送romeo.txt的實際數據。
這個例子展示瞭如何用套接字創建一個底層的網路連接。套接字可以和網頁伺服器、郵件伺服器或其它許多類型的伺服器通信。你要做就是找到描述這個協議的文檔,然後依據協議編寫發送和接收的代碼。
因為我們用得最多的是HTTP協議,所以在Python有一個專門設計,用來支持HTTP協議的特定庫,用來檢索網上的文檔和數據。
下一節將介紹這個庫。