python 网络编程学习笔记

注:此博客为《python疯狂讲义》的学习笔记

文章目录

  • 一. 基础概念
    • 术语
    • 端口
    • 网络模型
    • 每层网络模块都有对应协议
    • python 网络模块
    • URL (Uniform Resource Locator)
  • 二 urllib 模块
    • urllib.parse
      • urlparse
      • 解析查询字符串 parse_qs, parse_qsl
      • urljoin
    • urllib.request
      • urlopen
      • Request
  • 三. Http模块
    • cookie
  • 四. socket
  • 五. 邮件处理
    • 1. 邮件发送
    • 2. 邮件接收
  • 六. 拓展学习
    • 1. 请求报文与相应报文
    • 2. 查看本机IP
    • 3. 查看端口
    • 5. UDP协议

一. 基础概念

术语

  • HTTP协议(HyperText Transfer Protocol,超文本传输协议):是一种发布和接收 HTML页面的方法。
  • HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)简单讲是HTTP的安全版,在HTTP下加入SSL层。

端口

端口是一个 16 位的整数,用于表示将数据交给哪个通信程序处理。 因此,端口就是应用程序 与外界交流的出入口,它是一种抽象的软件结构,包括一些数据结构和 I/O (输入/输出) 缓冲区。 不同的应用程序处理不同端 口上的数据,在同一台机器中不能有两个程序使用同一个端口 。 端 口号可以为 0~65535 ,通常将端口分为如下三类。
  • 公认端口( Well Known Port) :喘口号为 0~1023 , 它们紧密地绑定(Binding) 一些特定 的服务。

  • 注册端口(Registered Port):端口号为 1024~49151 ,它们松散地结II定一些服务。应用程序 通常应该使用这个范围内的端口 。

  • 动态和/或私有端口( Dynamic and/or Private Port) : 端口号为 49152~65535,这些端口是 应用程序使用的动态端口,应用程序一般不会主动使用这些端口 。

网络模型

python 网络编程学习笔记_第1张图片

每层网络模块都有对应协议

python 网络编程学习笔记_第2张图片
其中 ICMP ( Internet Control Message Protocol 〕、 IGMP Cinternet Group Manage Protocol)、 ARP (Address Resolution Protocol )、 RARP C Reverse Address Resolution Protocol) 等协议都可认为是 IP 协议族的子协议。

python 网络模块

传输层协议主要是 TCP 和 UDP, Python 提供了 socket 等模块针对传输层协议进行编程。
python 网络编程学习笔记_第3张图片

URL (Uniform Resource Locator)

URL 可以由协议名 、主机、端口和资源路径组成,即满足以下格式:

protocol ://host :port/path/…/[?query-string][#anchor] 
# query-string:参数,发送给http服务器的数据
# anchor:锚(跳转到网页的指定锚点位置)

例如如下的 URL 地址:
http://www.crazyit.org/index.php

二 urllib 模块

urllib 模块则包含了多个用于处理 URL 的子模块。 );

  • urllib. request:这是最核心的子模块,它包含了打开和读取 URL 的各种函数。 );
  • urllib.error: 主要包含由 urllib.request 子模块所引发的各种异常。 );
  • urllib.parse: 用于解析 URL。 );
  • urllib.robotparser: 主要用于解析 robots.txt 文件。

通过使用 urllib 模块可以打开任意 URL 所指向的资源,就像打开本地文件一样,这样程序就 能完整地下载远程页面。如果再与第 10 章介绍的 re 模块结合使用,那么程序完全可以提取页面中 各种信息,这就是所谓的“网络爬虫”的初步原理。

在Python2.x中,urllib分为urllib和urllib2两个模块,前者用于简单下载,后者可用于http验证,cookie管理

urllib.parse

urlparse

属性名 元组索引 返回值 属性名 元组索引 返回值
scheme 0 fragment 5
netloc 1 主机和端口 username None
path 2 password None
params 3 资源路径附加参数 hostname None
query 4 查询字符串 port None
result = urlparse('http://www.crazyit.org:80/index.php;yeeku?name=fkit#frag')
print(result)
# 通过属性名和索引来获取URL的各部分
print('资源路径:', result.path, result[2])
print('参数:', result.params, result[3])
print('查询字符串:', result.query, result[4])
print('fragment:', result.fragment, result[5])
print(result.geturl())
# 输出
资源路径: /index.php /index.php
参数: yeeku yeeku
查询字符串: name=fkit name=fkit
fragment: frag frag
http://www.crazyit.org:80/index.php;yeeku?name=fkit#frag

解析查询字符串 parse_qs, parse_qsl

# 解析查询字符串,返回dict
result = parse_qs('name=fkit&name=%E7%96%AF%E7%8B%82java&age=12')
print(result)
# 解析查询字符串,返回list
result = parse_qsl('name=fkit&name=%E7%96%AF%E7%8B%82java&age=12')
print(result)
# 将列表格式的请求参数恢复成请求参数字符串
print(urlencode(result))
# 输出
{'name': ['fkit', '疯狂java'], 'age': ['12']}
[('name', 'fkit'), ('name', '疯狂java'), ('age', '12')]	
name=fkit&name=%E7%96%AF%E7%8B%82java&age=12

urljoin

# 被拼接URL不以斜线开头
result = urljoin('http://www.crazyit.org/users/login.html', 'help.html')
print(result) # http://www.crazyit.org/users/help.html
result = urljoin('http://www.crazyit.org/users/login.html', 'book/list.html')
print(result) # http://www.crazyit.org/users/book/list.html
# 被拼接URL以斜线(代表根路径path)开头
result = urljoin('http://www.crazyit.org/users/login.html', '/help.html')
print(result) # http://www.crazyit.org/help.html
# 被拼接URL以双斜线(代表绝对URL)开头
result = urljoin('http://www.crazyit.org/users/login.html', '//help.html')
print(result) # http://help.html

urllib.request

urlopen

urllib.request.urlopen(url, data=None).
urllib.request.urlopen(urllib.request.Request).

  • 该方法用于打开 url 指定的资源, 并从中读取数据。根据请求 url 的不同, 该方法的返回值会发生动 态改变。 如果 url 是一个 HTTP 地址, 那么该方法返回一个http.client.HTTP Response 对象。
  • 使用data属性向被请求的url发送数据
params = urllib.parse.urlencode({'name': 'fkit', 'password': '123888'})

f=urlopen("http://localhost:8080/test/post.jsp", data=params)

## 等价于使用附加参数,如下
#将请求参数添加到URL的后面
url = 'http://localhost:8080/test/get.jsp?%s' % params
f = urlopen(url=url)

Request

(1) 发送PUT请求

params = 'put请求数据'.encode('utf-8')
# 创建Request对象,设置使用PUT请求
req = Request(url='http://localhost:8080/test/put',
    data=params, method='PUT')
req.add_header('Referer', 'http://www.crazyit.org/')
with urlopen(req) as f:
	print(f.status)
	print(f.read().decode('utf-8'))

三. Http模块

cookie

例:

import urllib.request as ur
import http.cookiejar as hc, urllib.parse

# 以指定文件创建CookieJar对象,对象将可以把cookie保存在文件中
cookie_jar = hc.MozillaCookieJar('coockie_info.txt')
cookie_processor = ur.HTTPCookieProcessor(cookie_jar)
opener = ur.build_opener(cookie_processor)

# 定义模拟Chrome浏览器的user_agent
user_agent = r'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36' \
    r' (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'
# 定义请求头
headers = {'User-Agent':user_agent, 'Connection':'keep-alive'}

#-------------下面代码发送登录的POST请求----------------
# 定义登录系统的请求参数
params = {'name':'crazyit.org', 'pass':'leegang'}
postdata = urllib.parse.urlencode(params).encode()
# 创建向登录页面发送POST请求的Request
request = ur.Request('http://localhost:8080/test/login.jsp',
    data = postdata, headers = headers)
# 使用OpenerDirector发送POST请求
response = opener.open(request)
print(response.read().decode('utf-8'))

# 将cookie信息写入磁盘文件
cookie_jar.save(ignore_discard=True, ignore_expires=True)  # ①

#-------------下面代码发送访问被保护资源的GET请求----------------
# 创建向"受保护页面"发送GET请求的Request
request = ur.Request('http://localhost:8080/test/secret.jsp',
    headers=headers)
response = opener.open(request)
print(response.read().decode())

四. socket

server.py示例

s = socket.socket()
# 将socket绑定到本机IP和端口
s.bind(('192.168.43.36', 3000))
# 服务端开始监听来自客户端的连接
s.listen()
while True:
    # 每当接收到客户端socket的请求时,该方法返回对应的socket和远程地址
    c, addr = s.accept()
    print('连接地址:', addr)
    c.send('您好,您收到了服务器的新年祝福!'.encode('utf-8'))
    # 关闭连接
    c.close()

client.py示例
s = socket.socket()

# 连接远程主机
s.connect(('192.168.43.36', 3000))   
rec = s.recv(1024).decode('utf-8')

以上a.accept()才用阻塞的方式接收消息。
通过 selectors 可实现监听消息。

五. 邮件处理

1. 邮件发送

  • 连接 SMTP 服务器,并使用用户名、密码登录服务器。
  • 创建 Emai!Message 对象,该对象代表邮件本身。
  • 调用代表与 SMTP 服务器连接的对象的 sendmail()方法发送邮件

主要用到的模块:smtplib,email.message.EmailMessage

2. 邮件接收

使用 poplib 收取邮件可分为两步。

  • 使用 poplib.POP3 或 poplib.POP3_SSL 按 POP3 协议从服务器端下载邮件。
  • 使用 email.parser.Parser或 email.parser.BytesParser解析邮件件内容,得到 EmailMessage 对象
  • 从 EmailMessage 对象中读取邮件内容。

主要用到的模块:poplib,email.parser,email.policy

六. 拓展学习

1. 请求报文与相应报文

详细参考

  1. 请求报文

实例:
python 网络编程学习笔记_第4张图片
结构图:
python 网络编程学习笔记_第5张图片
常见报文头属性

名称 说明
Accept 告诉服务端 客户端接受什么类型的响应 一个或多个MIME类型
Cookie
Refere 表示这个请求是从哪个URL过来的 url
Cache-Control 是否在客服端缓存
User-Agent
其它
  1. 响应报文

(1)实例
python 网络编程学习笔记_第6张图片
(2)响应状态码

  • 1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急…
  • 2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
  • 3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
  • 4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
  • 5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。
    (3)常见报文头属性
说明
Cache-Control: max-age=3600 让客户端对响应内容缓存3600秒,也即在3600秒内,如果客户再次访问该资源,直接从客户端的缓存中返回内容给客户,不要再从服务端获取
ETag:“…” 当服务端资源发生变化,这个ETag就会相应发生变化。可以让客户端“更智能”地处理什么时候要从服务端取资源,什么时候可以直接从缓存中返回响应。
Location: http://www.iteye.com 其实是让客户端再发一个请求到A页面
Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 服务端可以设置客户端的Cookie

2. 查看本机IP

cmd: ipconfig/all

3. 查看端口

目的
查看所有端口使用情况 netstat -ano
查看特定端口 netstat -ano

5. UDP协议

  • UDP (User Datagram Protocol,用户数据报协议〉虽然目前 UDP 协议的应用不如TCP 协议广泛,但 UDP 依然是一种非常实用和可行的网络传输层协议。 尤其是在一些实时性很强的应用场景中,比如网络游戏、视频会议等, UDP 协议的快速能力更具有独特的魅力。
  • UDP 是一种面向非连接的协议,面向非连接指的是在正式通信前不必与对方先建立连接,不 管对方状态就直接发送数据。 至于对方是否可以接收到这些数据, UDP 协议无法控制,所以说 UDP 是一种不可靠的协议。 UDP 协议适用于一次只传送少量数据、对可靠性要求不高的应用环境。
  • UDP 协议的主要作用是完成网络数据流和数据报之间的转换。在信息的发送端, UDP 协议 将网络数据流封装成数据报,然后将数据报发送出去;在信息的接收端, UDP 协议将数据报转换 成实际数据内容。

可以认为 UDP协议的 socket类似于码头,数据报则类似于集装箱。 码头的作用就· ‘益,是负责友送、接收集装箱, 而 socket 的作用则是发送、接收数据报。 因此, 对于基于| UDP 协议的通信双方而言,没有所谓的客户 端和服务器端的概念。

你可能感兴趣的:(python,python,urllib)