笔记格式
套接字不同域的通信原理:AF_INET, AF_UNIX
常见的套接字socket的分类:SOCK_STREAM, SOCK_DGRAM
一个最简单的抓取网络信息的python程序
如何通过HTTP协议抓取imag图片?
如何用urllib检索网络信息?
BeautifulSoup
1. 套接字的域问题
AF_INET域socket通信过程
典型的TCP/IP四层模型的通信过程。发送方、接收方依赖IP:Port来标识,即将本地的socket绑定到对应的IP端口上,发送数据时,指定对方的IP端口,经过Internet,可以根据此IP端口最终找到接收方;接收数据时,可以从数据包中获取到发送方的IP端口。
AF_INET.png
AF_UNIX域socket通信过程
典型的本地IPC,类似于管道,依赖路径名标识发送方和接收方。类似本地通信。
BTW:进程间通信IPC (InterProcess Communication)
https://www.jianshu.com/p/c1015f5ffa74
AF_UNIX.png
2. 常见的socket(套接字)分类
socket是什么
1.1 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
1.2 建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。
1.3 socket是应用层和传输层间的桥梁,简单说就是包装应用层信息,并且把这些信息传到传输层那边。
socket
socket2
socket3
socket4
SOCK_STREAM
2.1 是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料(如文件)传送。
2.2 SOCK_STREAM是基于TCP的,数据传输比较有保障。
2.3 SOCK_STREAM 是数据流,一般是tcp/ip协议的编程
SOCK_DGRAM
3.1 是无保障的面向消息的socket,主要用于在网络上发广播信息。
3.2 SOCK_DGRAM是基于UDP的,专门用于局域网,基于广播
3.3 SOCK_DGRAM分是数据抱,是udp协议网络编程
基于传输层差异,4种类型的Socket:
(1)基于TCP的Socket:提供给应用层可靠的流式数据服务,使用TCP的Socket应用程序协议:BGP,HTTP,FTP,TELNET等。优点:基于数据传输的可靠性。
(2)基于UDP的Socket:适用于数据传输可靠性要求不高的场合。基于UDP的Socket应用程序或协议有:RIP,SNMP,L2TP等。
(3)基于RawIp的Socket:非连接,不可靠的数据传输。特点:能使应用程序直接访问网络层。基于RawIp的Socket有ping ,tracert,ospf等。
(4)基于链路层的Socket。为IS-IS协议提供的Socket接口。使IS-IS协议可通过Socket直接访问链路层。非连接,不可靠通信服务。
3. 一个最简单的抓取网络信息的python程序
首先要调用python的专用库socket
定义socket的作用域和报文方式
定义host(web server)和IP端口
做一些简单操作 get 就是获取信息,定义通信协议HTTP。
取信息时encode,信息拿回来再decode。
import socket
mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
mysock.connect(('data.pr4e.org', 80))
cmd = 'GET http://data.pr4e.org/romeo.txt HTTP/1.0\r\n\r\n'.encode()
mysock.send(cmd)
while True:
data = mysock.recv(20)
if (len(data) < 1):
break
print(data.decode(),end='')
mysock.close()
3.2
encode & decode
sokcet
4. 如何通过HTTP协议抓取imag图片
一般网络信息用的是HTTP(port 80), HTTPS(port 443)。前一个是不加密不安全链接,后一个是加密链接。
拿回来的信息需要减去报头并且解码(重新编码)。
2.1 首先,虽然每次都是要求5120个字符,但是返回的并不确定(网络网速限制),所以要记录起止点(count,len)。根据这些起止点分割成一段一段的报文,然后再剪去报头。这个报头是协议HTTP中定义的这一串 “\r\n\r\n”
2.2 为什么每次返回信息长度不定?这是因为HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。HTTP有两类报文:请求报文和响应报文。
HTTP-packets
2.3 自己跟着写一遍我终于知道这代码啥意思了.....附上比代码长的个人注释。
import socket
import time
host = 'data.pr4e.org'
port = 80
mysock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
mysock.connect((host,port))
mysock.sendall(b'GET http://data.pr4e.org/cover3.jpg HTTP/1.0\r\n\r\n')
count = 0
picture = b""
while True:
data = mysock.recv(5120) # get one packet of data
if (len(data)<1):break
time.sleep(0.25)
count = count + len(data) #how many length of data we have been received
print(len(data),count) # use len(data) to check how long this packet is.
picture = picture + data # adding all the received packets to be a picture file (binary)
mysock.close()
# Look for the end of the header (2 CRLF)
pos = picture.find(b"\r\n\r\n") #using these four charaters to seperate the whole picture into small packets
print('Header length', pos)
print(picture[:pos].decode())
# Skip past the header and save the picture data
picture = picture[pos+4:] #it is to remove these four charaters "\r\n\r\n"
fhand = open("stuff.jpg", "wb") #create a picture enconding file
fhand.write(picture) # transform the data into the file
fhand.close()
5. 如何用urllib检索网络信息?
这个库好方便又好简单,我决定忘记抛弃上面的socket。直接抓取URL中的内容,返回decode一下就可以了。
import urllib.request
fhand = urllib.request.urlopen('http://data.pr4e.org/romeo.txt')
for line in fhand:
print(line.decode().strip())
6. BeautifulSoup是什么
为了方便点,不用每次都放到路径里,可以在anaconda安装。
conda install -c anaconda beautifulsoup4
参考资料: