爬蟲(chóng)遇到 Socket,莫慌,肝就完了!
點(diǎn)擊上方“AirPython”,選擇“加為星標(biāo)”
第一時(shí)間關(guān)注 Python 原創(chuàng)干貨!

1. 前言
Socket 被稱(chēng)為套接字,是對(duì) TCP/IP 協(xié)議的封裝,它是傳輸層和應(yīng)用層間的抽象層
相比 HTTP 的短連接通信方式,Socket 可實(shí)現(xiàn)客戶(hù)端和服務(wù)器的長(zhǎng)連接通信
Fiddler、Charles 只能抓取應(yīng)用層的數(shù)據(jù),如果你想抓其他層,比如:網(wǎng)絡(luò)層、傳輸層、數(shù)據(jù)鏈路層的數(shù)據(jù),強(qiáng)烈建議使用:Wireshark
2. Wireshark 基礎(chǔ)
Wireshark 是一個(gè)功能非常強(qiáng)大的數(shù)據(jù)流截取工具,不僅能監(jiān)測(cè) HTTP(S) 請(qǐng)求,還能監(jiān)測(cè)?TCP/UDP 請(qǐng)求,OSI 七層模型上的數(shù)據(jù)基本上都能被抓取到
2-1? 主界面

主界面包含:
菜單欄
工具欄
數(shù)據(jù)過(guò)濾區(qū)域
數(shù)據(jù)列表展示區(qū)域
按層次展示數(shù)據(jù)區(qū)域
數(shù)據(jù)字節(jié)區(qū)域
2-2??數(shù)據(jù)列表展示區(qū)域
該區(qū)域用于展示經(jīng)過(guò)特定網(wǎng)絡(luò)端口的報(bào)文數(shù)據(jù),可以自定義數(shù)據(jù)列表及顯示方式
比如:修改報(bào)文時(shí)間的顯示格式

每一條報(bào)文直觀顯示了:報(bào)文編號(hào)、時(shí)間、源 ip 地址、目標(biāo) ip 地址、協(xié)議名稱(chēng)、報(bào)文長(zhǎng)度、報(bào)文詳細(xì)信息(端口號(hào)、flags 字段)
2-3? 按層次展示數(shù)據(jù)區(qū)域
該區(qū)域與報(bào)文對(duì)應(yīng)關(guān)系如下:
Frame??對(duì)應(yīng)物理層,一般用于展示物理層的數(shù)據(jù)幀概況
Ethernet II? 對(duì)應(yīng)數(shù)據(jù)鏈路層,用于展示數(shù)據(jù)鏈路層以太網(wǎng)幀頭部信息
Internet Protocol Version 4??對(duì)應(yīng)網(wǎng)絡(luò)層,用于展示 IP 包頭部信息
Transmission Control Protocol??對(duì)應(yīng)傳輸層,用于展示傳輸層 T 的數(shù)據(jù)段頭部信息,包含 TCP/UDP 等
Hypertext Transfer Protocol? 對(duì)應(yīng)應(yīng)用層,用于顯示應(yīng)用層的數(shù)據(jù)信息
2-4??數(shù)據(jù)過(guò)濾區(qū)域
數(shù)據(jù)過(guò)濾區(qū)域方便我們對(duì)報(bào)文進(jìn)行篩選過(guò)濾,快讀定位到我們想要的數(shù)據(jù)
這里支持通過(guò) ip 地址、端口號(hào)、操作符、邏輯運(yùn)算符、協(xié)議名稱(chēng)進(jìn)行過(guò)濾
#?1.通過(guò)協(xié)議名稱(chēng)過(guò)濾
#?比如:只顯示tcp協(xié)議的數(shù)據(jù)包
tcp
#?2.通過(guò)端口號(hào)過(guò)濾
#?顯示源或者目標(biāo)協(xié)議為tcp,并且端口號(hào)為80的數(shù)據(jù)包
tcp.port?==?80
#?2.1?顯示源協(xié)議名稱(chēng)為tcp,端口號(hào)為80的數(shù)據(jù)包
tcp.srcport?==?80
#?2.2?顯示目標(biāo)協(xié)議名稱(chēng)為tcp,端口號(hào)為80的數(shù)據(jù)包
tcp.dstport?==?80
#?3.ip地址過(guò)濾
#?顯示源ip地址或者目標(biāo)ip地址滿(mǎn)足條件的數(shù)據(jù)包
ip.addr?==?192.168.1.101
#?3.1?顯示源ip地址滿(mǎn)足條件的數(shù)據(jù)包
ip.src?==?192.168.1.101
#?3.2?顯示目標(biāo)ip地址滿(mǎn)足條件的數(shù)據(jù)包
ip.dst?==?192.168.1.101
# 4.邏輯運(yùn)算符,包含:and(并且)/or(或者)/not (非)
#?通過(guò)ip地址、協(xié)議、端口號(hào)進(jìn)行過(guò)濾
ip.src?==?192.168.0.102?and?tcp.port==630683. 實(shí)戰(zhàn)
以常見(jiàn)的 TCP 為例,我們?cè)诒镜啬M一個(gè) Socket 通信過(guò)程,然后使用?Wireshark 進(jìn)行抓包
這里,我們使用 Python 中的 socket 模塊快速擼一個(gè)
其中
服務(wù)端:綁定本地,并阻塞直到客戶(hù)端連接上,循環(huán)獲取客戶(hù)端發(fā)送過(guò)來(lái)的消息
客戶(hù)端:通過(guò) ip 地址和端口號(hào)連接服務(wù)器,向服務(wù)端發(fā)送消息,并解析服務(wù)端發(fā)送過(guò)來(lái)的消息
3-1? 服務(wù)端
import?socket
#?服務(wù)端的Socket套接字對(duì)象
server_socket?=?socket.socket()
#?綁定地址+ip
server_socket.bind(('192.168.0.102',?6666))
#?監(jiān)聽(tīng)連接請(qǐng)求
server_socket.listen(5)
#?開(kāi)始阻塞,等待客戶(hù)端連接
print('服務(wù)端阻塞,等待客戶(hù)端連接...')
conn,?address?=?server_socket.accept()
while?True:
????data?=?conn.recv(1024).decode()
????if?data?==?'exit':
????????print('通信結(jié)束!')
????????break
????else:
????????print('接受到客戶(hù)端-{}發(fā)送過(guò)來(lái)的消息,內(nèi)容是:{}'.format(address,?data))
????#?返回消息給客戶(hù)端
????conn.sendall("服務(wù)端收到消息!".encode())
#?關(guān)閉連接
conn.close()
3-2? 客戶(hù)端
import?socket
#?客戶(hù)端的Socket套接字對(duì)象
client_socket?=?socket.socket()
#?連接Socket服務(wù)
client_socket.connect(('192.168.0.102',?6666))
while?True:
????#?等待用戶(hù)輸入內(nèi)容
????content?=?input('輸入要發(fā)送的內(nèi)容:').strip()
????#?發(fā)送給Socket服務(wù)端
????client_socket.sendall(content.encode())
????if?content?==?'exit':
????????print('客戶(hù)端終止通信!')
????????break
????else:
????????#?接受服務(wù)端發(fā)來(lái)的消息
????????content_from_server?=?client_socket.recv(1024).decode()
????????print('接受到服務(wù)端的消息:',?content_from_server)
#?關(guān)閉連接
client_socket.close()
3-3? 抓包
需要注意的是,使用 Wireshark 抓取本機(jī)到本機(jī)的數(shù)據(jù)包,需要切換監(jiān)聽(tīng)網(wǎng)絡(luò)端口為:Loopback:lo0

運(yùn)行代碼,正常模擬客戶(hù)端和服務(wù)端之間的數(shù)據(jù)通訊
使用?協(xié)議 +?端口號(hào),在 wireshark 中進(jìn)行數(shù)據(jù)過(guò)濾,即可抓取到完整的傳輸數(shù)據(jù)

4. 最后
對(duì)于移動(dòng)端 Socket 通訊的數(shù)據(jù)抓取,如果是 PC,可以將本機(jī)作為熱點(diǎn)開(kāi)放出去,然后手機(jī)連接熱點(diǎn),wireshark?選擇對(duì)應(yīng)的網(wǎng)絡(luò)端口進(jìn)行抓包即可
而對(duì)于 Mac,建議打開(kāi)網(wǎng)絡(luò)共享后,將手機(jī)使用 USB 連接進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)的抓取
如果你覺(jué)得文章還不錯(cuò),請(qǐng)大家?點(diǎn)贊、分享、留言?下,因?yàn)檫@將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強(qiáng)動(dòng)力!
