PRO-005:模擬伺服器抓取客戶的請求協議資料

weixin_34006468發表於2019-01-18

本主題寫一個簡單的程式,抓取瀏覽器請求資料。從而瞭解HTTP協議的格式。本主題使用的技術:

  1. Socket程式設計;
  2. IO非同步多路複用API;
  3. 使用訊號,撲捉訊號(2:CTRL+C)來正常結束程式。

一、程式碼:

# coding =utf-8
import socket   # socket程式設計模組
import select   # 多路複用模組
import sys      # 系統呼叫
import signal
import os

# 方便傳送訊號滅掉這個程式
print('本程式ID:%d,可以使用kill滅之,如果在ipython中不方便結束的話!' % os.getpid())


# 這裡處理ctrl+c的訊號(方便ctrl+c退出)
def handle_int(signum, handler):
    print('程式中斷退出,訊號:%d' % signum, '處理器是:{}'.format(handler))
    sys.exit(0)


# 繫結對ctrl+c訊號的處理
signal.signal(signalnum=signal.SIGINT, handler=handle_int)

# 下面程式碼為了清晰思路,沒有做任何程式碼的異常處理
# 多路複用資料
io_inputs = []
io_outputs = []
io_error = []
# 建立socket
server_socket = socket.socket(
    socket.AF_INET,         # 網路地址族:常用的是internet網地址格式(IP地址)
    socket.SOCK_STREAM,     # 網路通訊方式:流與報文兩種
    socket.IPPROTO_TCP)     # 通訊協議:資料包的格式

# 繫結地址
server_address = ('', 9999)   # 地址包含IP地址與埠地址
server_socket.bind(server_address)
# 監聽
server_socket.listen(2)

# 把server_socket加入多路複用IO中
io_inputs.append(server_socket)

# 開始監控多路複用非同步IO(包含server_socket的連線,新連線的也加入,短線的刪除)
while True:
    ready_inputs, ready_outputs, ready_error = select.select(
        io_inputs, io_outputs, io_error, None)
    # 檢查返回值,並相應的處理,這裡我們只接收,不傳送,所以不處理輸出IO
    for fd in ready_inputs:
        # 伺服器IO與每個客戶的IO分開處理
        if fd == server_socket:   # 伺服器IO
            # 對伺服器IO的護處理:接收客戶連線
            client_socket, client_address = fd.accept()  # 這裡需要處理異常,就是伺服器掛掉,退出應用
            print('客戶連線:IP=%s,PORT=%d' % client_address)  # 這裡需要一個元組,直接使用
            # 把新連線的客戶加入多路複用監控處理
            io_inputs.append(client_socket)
        else:   # 每個客戶的IO
            # 對客戶IO是接收資料請求:請求都是HTTP協議的請求協議
            while True:
                buffer = fd.recv(1024*4, 0)     # 接收緩衝大小與接收標記
                if not buffer:
                    fd.close()                  # 關閉
                    io_inputs.remove(fd)        # 客戶退出
                    print('客戶連退出')
                    break
                else:
                    print(buffer.decode('UTF-8'))

二、執行效果

13618185-4adea8a09d1b1ed3.png
在PyCharm下執行效果

在終端下執行,請使用CTRL+C結束。

三、撲捉到的瀏覽器請求協議資料

GET / HTTP/1.1
Host: localhost:9999
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Upgrade-Insecure-Requests: 1
Cookie: username-localhost-8888="2|1:0|10:1547792772|23:username-localhost-8888|44:ZTEyMGU2MmIxOTU5NGQyNDg4NTg4OGZkYTQ1OTk5MjY=|b153a00c7702d49e917acdac6d5343298f681fc91e368ebd2cfc88adb15dccb3"; username-localhost-8889="2|1:0|10:1547621721|23:username-localhost-8889|44:NGE5ODk0NTM0YTMxNGM1ODk4NWI5MGFlOWIzNjc2ZGY=|f7e6e3b82d51248a6afa17355c1e3248844e509996319cfda092f38983124264"; _xsrf=2|3ed5cde2|333f93d1f4756a5072a7443c8a91e406|1545622163
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.2 Safari/605.1.15
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
Connection: keep-alive


----

注意最後由有兩個空行。一個空行表示HEADER行與資料體的分割。最後空行是GET方法沒有資料體。

相關文章