小言_互联网的博客

爬虫遇到 Socket,莫慌,肝就完了!

292人阅读  评论(0)

点击上方“AirPython”,选择“加为星标”

第一时间关注 Python 原创干货!

1. 前言

Socket 被称为套接字,是对 TCP/IP 协议的封装,它是传输层和应用层间的抽象层

相比 HTTP 的短连接通信方式,Socket 可实现客户端和服务器的长连接通信

Fiddler、Charles 只能抓取应用层的数据,如果你想抓其他层,比如:网络层、传输层、数据链路层的数据,强烈建议使用:Wireshark

2. Wireshark 基础

Wireshark 是一个功能非常强大的数据流截取工具,不仅能监测 HTTP(S) 请求,还能监测 TCP/UDP 请求,OSI 七层模型上的数据基本上都能被抓取到

2-1  主界面

主界面包含:

  • 菜单栏

  • 工具栏

  • 数据过滤区域

  • 数据列表展示区域

  • 按层次展示数据区域

  • 数据字节区域

2-2  数据列表展示区域

该区域用于展示经过特定网络端口的报文数据,可以自定义数据列表及显示方式

比如:修改报文时间的显示格式

每一条报文直观显示了:报文编号、时间、源 ip 地址、目标 ip 地址、协议名称、报文长度、报文详细信息(端口号、flags 字段)

2-3  按层次展示数据区域

该区域与报文对应关系如下:

  • Frame  对应物理层,一般用于展示物理层的数据帧概况

  • Ethernet II  对应数据链路层,用于展示数据链路层以太网帧头部信息

  • Internet Protocol Version 4  对应网络层,用于展示 IP 包头部信息

  • Transmission Control Protocol  对应传输层,用于展示传输层 T 的数据段头部信息,包含 TCP/UDP 等

  • Hypertext Transfer Protocol  对应应用层,用于显示应用层的数据信息

2-4  数据过滤区域

数据过滤区域方便我们对报文进行筛选过滤,快读定位到我们想要的数据

这里支持通过 ip 地址、端口号、操作符、逻辑运算符、协议名称进行过滤


   
  1. 1.通过协议名称过滤
  2. # 比如:只显示tcp协议的数据包
  3. tcp
  4. 2.通过端口号过滤
  5. # 显示源或者目标协议为tcp,并且端口号为 80的数据包
  6. tcp.port ==  80
  7. 2.1 显示源协议名称为tcp,端口号为 80的数据包
  8. tcp.srcport ==  80
  9. 2.2 显示目标协议名称为tcp,端口号为 80的数据包
  10. tcp.dstport ==  80
  11. 3.ip地址过滤
  12. # 显示源ip地址或者目标ip地址满足条件的数据包
  13. ip.addr ==  192.168 .1 .101
  14. 3.1 显示源ip地址满足条件的数据包
  15. ip.src ==  192.168 .1 .101
  16. 3.2 显示目标ip地址满足条件的数据包
  17. ip.dst ==  192.168 .1 .101
  18. # 4.逻辑运算符,包含:and(并且)/or(或者)/not (非)
  19. # 通过ip地址、协议、端口号进行过滤
  20. ip.src ==  192.168 .0 .102 and tcp.port== 63068

3. 实战

以常见的 TCP 为例,我们在本地模拟一个 Socket 通信过程,然后使用 Wireshark 进行抓包

这里,我们使用 Python 中的 socket 模块快速撸一个

其中

  • 服务端:绑定本地,并阻塞直到客户端连接上,循环获取客户端发送过来的消息

  • 客户端:通过 ip 地址和端口号连接服务器,向服务端发送消息,并解析服务端发送过来的消息

3-1  服务端


   
  1. import socket
  2. # 服务端的Socket套接字对象
  3. server_socket = socket.socket()
  4. # 绑定地址+ip
  5. server_socket.bind(( '192.168.0.102'6666))
  6. # 监听连接请求
  7. server_socket.listen( 5)
  8. # 开始阻塞,等待客户端连接
  9. print( '服务端阻塞,等待客户端连接...')
  10. conn, address = server_socket.accept()
  11. while True:
  12.     data = conn.recv( 1024).decode()
  13.      if data ==  'exit':
  14.          print( '通信结束!')
  15.          break
  16.      else:
  17.          print( '接受到客户端-{}发送过来的消息,内容是:{}'.format(address, data))
  18.     # 返回消息给客户端
  19.     conn.sendall( "服务端收到消息!".encode())
  20. # 关闭连接
  21. conn. close()

3-2  客户端


   
  1. import socket
  2. # 客户端的Socket套接字对象
  3. client_socket = socket.socket()
  4. # 连接Socket服务
  5. client_socket.connect(( '192.168.0.102'6666))
  6. while True:
  7.     # 等待用户输入内容
  8.     content = input( '输入要发送的内容:').strip()
  9.     # 发送给Socket服务端
  10.     client_socket.sendall(content.encode())
  11.      if content ==  'exit':
  12.          print( '客户端终止通信!')
  13.          break
  14.      else:
  15.         # 接受服务端发来的消息
  16.         content_from_server = client_socket.recv( 1024).decode()
  17.          print( '接受到服务端的消息:', content_from_server)
  18. # 关闭连接
  19. client_socket. close()

3-3  抓包

需要注意的是,使用 Wireshark 抓取本机到本机的数据包,需要切换监听网络端口为:Loopback:lo0

运行代码,正常模拟客户端和服务端之间的数据通讯

使用 协议 + 端口号,在 wireshark 中进行数据过滤,即可抓取到完整的传输数据

4. 最后

对于移动端 Socket 通讯的数据抓取,如果是 PC,可以将本机作为热点开放出去,然后手机连接热点,wireshark 选择对应的网络端口进行抓包即可

而对于 Mac,建议打开网络共享后,将手机使用 USB 连接进行网络数据的抓取

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!

推荐阅读

Python 爬虫,推荐一款简单的抓包工具

带你用 Python 实现自动化群控(入门篇)

我花 1 分钟写了一段爬虫,帮助小姐姐解放了双手


转载:https://blog.csdn.net/hsh881025/article/details/110412714
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场