当前位置: 首页 > news >正文

Python实战(4)-网络编程

本章将通过示例展示如何使用Python来编写以各种方式使用网络(如互联网)的程序。Python提供了强大的网络编程支持,有很多库实现了常见的网络协议以及基于这些协议的抽象层,让你能够专注于程序的逻辑,而无需关心通过线路来传输比特的问题。另外,对于有些协议格式,可能没有处理它们的现成代码,但编写起来也很容易,因为Python很擅长处理字节流中的各种模式(从本书前面介绍的各种处理文本文件的方式中,你可能领教了这一点)​。鉴于Python提供的网络工具众多,这里只能简要地介绍它的网络功能。

标准库中有很多网络模块,其他地方也有不少。有些网络模块明显主要是处理网络的,但还有几个其实也是与网络相关的,如处理各种数据编码以便通过网络传输的模块。这里精挑细选了几个模块进行介绍。

模块socket

网络编程中的一个基本组件是套接字(socket)​。套接字基本上是一个信息通道,两端各有一个程序。这些程序可能位于(通过网络相连的)不同的计算机上,通过套接字向对方发送信息。在Python中,大多数网络编程都隐藏了模块socket的基本工作原理,不与套接字直接交互。

套接字分为两类:服务器套接字和客户端套接字。创建服务器套接字后,让它等待连接请求的到来。这样,它将在某个网络地址(由IP地址和端口号组成)处监听,直到客户端套接字建立连接。随后,客户端和服务器就能通信了。客户端套接字处理起来通常比服务器端套接字容易些,因为服务器必须准备随时处理客户端连接,还必须处理多个连接;而客户端只需连接,完成任务后再断开连接即可。本章后面将介绍如何使用SocketServer等类和Twisted框架进行服务器端编程。

套接字是模块socket中socket类的实例。实例化套接字时最多可指定三个参数:一个地址族(默认为socket.AF_INET)​;是流套接字(socket.SOCK_STREAM,默认设置)还是数据报套接字(socket.SOCK_DGRAM)​;协议(使用默认值0就好)​。创建普通套接字时,不用提供任何参数。

服务器套接字先调用方法bind,再调用方法listen来监听特定的地址。然后,客户端套接字就可连接到服务器了,办法是调用方法connect并提供调用方法bind时指定的地址(在服务器端,可使用函数socket.gethostname获取当前机器的主机名)​。这里的地址是一个格式为(host, port)的元组,其中host是主机名(如www.example.com)​,而port是端口号(一个整数)​。方法listen接受一个参数——待办任务清单的长度(即最多可有多少个连接在队列中等待接纳,到达这个数量后将开始拒绝连接)​。

服务器套接字开始监听后,就可接受客户端连接了,这是使用方法accept来完成的。这个方法将阻断(等待)到客户端连接到来为止,然后返回一个格式为(client,address)的元组,其中client是一个客户端套接字,而address是前面解释过的地址。服务器能以其认为合适的方式处理客户端连接,然后再次调用accept以接着等待新连接到来。这通常是在一个无限循环中完成的。注意这里讨论的服务器编程形式称为阻断(同步)网络编程。后面你将看到非阻断(异步)网络编程示例,以及如何使用线程来同时处理多个客户端。为传输数据,套接字提供了两个方法:send和recv(表示receive)​。要发送数据,可调用方法send并提供一个字符串;要接收数据,可调用recv并指定最多接收多少个字节的数据。如果不确定该指定什么数字,1024是个不错的选择。

代码清单14-1和14-2展示了最简单的客户端程序和服务器程序。如果在同一台机器上运行它们(先运行服务器程序)​,服务器程序将打印一条收到连接请求的消息,然后客户端程序将打印它从服务器那里收到的消息。在服务器还在运行时,可运行多个客户端。在客户端程序中,通过将gethostname调用替换为服务器机器的主机名,可分别在两台通过网络连接的机器上运行这两个程序。

注意可使用的端口号通常受到限制。在Linux或UNIX系统中,需要有管理员权限才能使用1024以下的端口号。这些编号较小的端口是供标准服务使用的。例如,端口80供Web服务器使用。另外,使用Ctrl+C停止服务器后,可能需要等待一段时间才能使用该服务器原来使用的端口(否则,可能出现“地址已被占用”错误消息)​。

代码清单14-1 最简单的服务器

import socket
s = socket.socket()


host = socket.gethostname()
port = 1234
s.bind((host, port))


s.listen(5)
while True:
    c, addr = s.accept()
    print('Got connection from', addr)
    c.send('Thank you for connecting'.encode("utf-8"))
    c.close()

代码清单14-2 最简单的客户端

        import socket


        s = socket.socket()


        host = socket.gethostname()
        port = 1234


        s.connect((host, port))
        print(s.recv(1024))

server端运行效果:

在这里插入图片描述

client端运行效果:

在这里插入图片描述

模块urllib和urllib2

在可供使用的网络库中,urllib和urllib2可能是投入产出比最高的两个。它们让你能够通过网络访问文件,就像这些文件位于你的计算机中一样。只需一个简单的函数调用,就几乎可将统一资源定位符(URL)可指向的任何动作作为程序的输入。想想将这种功能与模块re结合起来使用都能做什么吧!你可下载网页、从中提取信息并自动生成研究报告。

模块urllib和urllib2的功能差不多,但urllib2更好一些。对于简单的下载,urllib绰绰有余。如果需要实现HTTP身份验证或Cookie,抑或编写扩展来处理自己的协议,urllib2可能是更好的选择。

打开远程文件

几乎可以像打开本地文件一样打开远程文件,差别是只能使用读取模式,以及使用模块urllib.request中的函数urlopen,而不是open(或file)​。

        >>> from urllib.request import urlopen
        >>> webpage = urlopen('http://www.python.org')

如果连接到了网络,变量webpage将包含一个类似于文件的对象,这个对象与网页http://www.python.org相关联。注意要在没有联网的情况下尝试使用模块urllib,可使用以file:打头的URL访问本地文件,如file:c:\text\somefile.txt(别忘了对反斜杠进行转义)​。urlopen返回的类似于文件的对象支持方法close、read、readline和readlines,还支持迭代等。假设要提取刚才所打开网页中链接About的相对URL,可使用正则表达式)​。

        >>> import re
        >>> text = webpage.read()
        >>> m = re.search(b'<a href="([^"]+)" .*?>about</a>', text, re.IGNORECASE)
        >>> m.group(1)
        '/about/'

获取远程文件

函数urlopen返回一个类似于文件的对象,可从中读取数据。如果要让urllib替你下载文件,并将其副本存储在一个本地文件中,可使用urlretrieve。这个函数不返回一个类似于文件的对象,而返回一个格式为(filename, headers)的元组,其中filename是本地文件的名称(由urllib自动创建)​,而headers包含一些有关远程文件的信息(这里不会介绍headers,如果你想更深入地了解它,请在有关urllib的标准库文档中查找urlretrieve)​。如果要给下载的副本指定文件名,可通过第二个参数来提供。

        urlretrieve('http://www.python.org', 'C:\\python_webpage.html')

这将获取Python官网的主页,并将其存储到文件C:\python_webpage.html中。如果你没有指定文件名,下载的副本将放在某个临时位置,可使用函数open来打开。但使用完毕后,你可能想将其删除,以免占用磁盘空间。要清空这样的临时文件,可调用函数urlcleanup且不提供任何参数,它将负责替你完成清空工作。

一些实用的函数

除了通过URL读取和下载文件外,urllib还提供了一些用于操作URL的函数,如下所示(这里假设你对URL和CGI略知一二)​。

❑ quote(string[, safe]):返回一个字符串,其中所有的特殊字符(在URL中有特殊意义的字符)都已替换为对URL友好的版本(如将~替换为%7E)​。如果要将包含特殊字符的字符串用作URL,这很有用。参数safe是一个字符串(默认为’/')​,包含不应像这样对其进行编码的字符。

❑ quote_plus(string[, safe]):类似于quote,但也将空格替换为加号。

❑ unquote(string):与quote相反。❑ unquote_plus(string):与quote_plus相反。urlencode(query[, doseq]):将映射(如字典)或由包含两个元素的元组(形如(key, value))组成的序列转换为“使用URL编码的”字符串。这样的字符串可用于CGI查询中(详细信息请参阅Python文档)​。

相关文章:

  • Liunx系统Microsoft SQL Server数据库还原
  • datawhale组队学习-大语言模型-task5:主流模型架构及新型架构
  • CentOS与Rocky 命令区别
  • python如何获取html中附件链接,并下载保存附件
  • 1.向量数据库milvus standalone单机版搭建
  • MobaXterm:全能终端工具如何重新定义远程开发与运维效率?
  • Linux 常用命令 - last 【显示历史登录用户列表】
  • 在coze工作流中将数据回写到飞书表格
  • ubuntu部署运行xinference全精度对话deepseek本地部署图文教程
  • WPS宏开发手册——使用、工程、模块介绍
  • 【后端】【Django】【ORM】SearchFilter 详解
  • Hive配置JDBC连接
  • Unity编辑器扩展快速回顾
  • Jackson使用ObjectNode对象实现JSON对象数据(一):增、删、改、查
  • springcloud是多个springboot项目分开的吗
  • CCF开源发展委员会常委会会议召开,共绘开源新蓝图
  • 怎样对比找到两个git仓库的差异
  • 不能将下载行为传输到IDM
  • 固定翼无人机姿态和自稳模式
  • 【语料数据爬虫】Python爬虫|批量采集讲话稿数据【范文网】(2)
  • 东莞“超级”音乐节五一出圈背后:文旅热力何以澎湃经济脉动
  • 五一期间7名游客接连被困青海荒漠,警方提醒严禁非法穿越
  • 中国人民银行:5月8日起降息,15日起降准
  • 应对美政策调整:中国重在开放与创新,维护好数据主权
  • 特朗普称不会为了和中国谈判而取消对华关税,外交部回应
  • 科技赋能文化体验,“五一”假期“海昏侯”人气创新高