使用 requests 库

抓取 ITFun 接口中的图片

pip install requests
from time import time
from threading import Thread
import requests


# 继承Thread类创建自定义的线程类
class Download(Thread):

    def __init__(self, url):
        super().__init__()
        self.url = url

    def run(self):
        filename = self.url[self.url.rfind('/') + 1:]
        resp = requests.get(self.url)

        # 存放到当前目录
        with open('./' + filename, 'wb') as f:
            f.write(resp.content)


def main():
    # 通过requests模块的get函数获取网络资源
    resp = requests.get('https://itfun.tv/api/v1/categories/back_end.json')

    # 将服务器返回的JSON格式的数据解析为字典
    result = resp.json()

    # print(data_model['courses'])

    for course in result['courses']:
        url = course['photo']
        # 通过多线程的方式实现图片下载
        Download(url).start()


if __name__ == '__main__':
    main()

练习

  • 将下载的图片,存在 ./photos/ 目录下。如果 photos 目录不存在,程序自动创建此目录。
  • 将以上代码改为:单线程下载
  • 将以上代码改为:直接调用 Thread 类实现多线程下载,而不是继承方式
  • 抓取 https://itfun.tv/course_categories 页面的所有图片(使用正则匹配),并多线程下载保存到本地。

套接字编程

套接字可以分为三类:

  • 流套接字(TCP套接字)
  • 数据报套接字
  • 原始套接字

TCP套接字

TCP套接字就是使用TCP协议提供的传输服务来实现网络通信的编程接口。在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。

在创建套接字对象后,要将其绑定到指定的IP地址和端口上。端口的取值范围是 0~65535,而 1024 以下的端口我们通常称之为著名端口(留给像FTP、HTTP、SMTP等著名服务使用的端口,有的地方也称之为周知端口),所以在绑定的时候,不要使用 1024 以下的端口。

创建服务端程序

from socket import socket, SOCK_STREAM, AF_INET
from datetime import datetime


def main():
    # 1.创建套接字对象并指定使用哪种传输服务
    # family=AF_INET - IPv4地址
    # family=AF_INET6 - IPv6地址
    # type=SOCK_STREAM - TCP套接字
    # type=SOCK_DGRAM - UDP套接字
    # type=SOCK_RAW - 原始套接字
    server = socket(family=AF_INET, type=SOCK_STREAM)
    # 2.绑定IP地址和端口(端口用于区分不同的服务)
    # 同一时间在同一个端口上只能绑定一个服务否则报错
    server.bind(('127.0.0.1', 6789))
    # 3.开启监听 - 监听客户端连接到服务器
    # 参数512可以理解为连接队列的大小
    server.listen(512)
    print('服务器启动开始监听...')
    while True:
        # 4.通过循环接收客户端的连接并作出相应的处理(提供服务)
        # accept方法是一个阻塞方法如果没有客户端连接到服务器代码不会向下执行
        # accept方法返回一个元组其中的第一个元素是客户端对象
        # 第二个元素是连接到服务器的客户端的地址(由IP和端口两部分构成)
        client, addr = server.accept()
        print(str(addr) + '连接到了服务器.')
        # 5.发送数据
        client.send(str(datetime.now()).encode('utf-8'))
        # 6.断开连接
        client.close()


if __name__ == '__main__':
    main()

macOS 需要安装 telnetWindows 请忽略

$ brew install telnet

尝试连接

telnet 127.0.0.1 6789

创建客户端程序

from socket import socket


def main():
    # 1.创建套接字对象默认使用IPv4和TCP协议
    client = socket()
    # 2.连接到服务器(需要指定IP地址和端口)
    client.connect(('127.0.0.1', 6789))
    # 3.从服务器接收数据
    print(client.recv(1024).decode('utf-8'))
    client.close()


if __name__ == '__main__':
    main()

UDP套接字

传输层除了有可靠的传输协议TCP之外,还有一种非常轻便的传输协议叫做用户数据报协议,简称UDP。TCP和UDP都是提供端到端传输服务的协议,二者的差别就如同打电话和发短信的区别,后者不对传输的可靠性和可达性做出任何承诺从而避免了TCP中握手和重传的开销,所以在强调性能和而不是数据完整性的场景中(例如传输网络音视频数据),UDP可能是更好的选择。可能大家会注意到一个现象,就是在观看网络视频时,有时会出现卡顿,有时会出现花屏,这无非就是部分数据传丢或传错造成的。在Python中也可以使用UDP套接字来创建网络应用,对此我们不进行赘述,有兴趣的读者可以自行研究。