一、HTTP协议简介
1. 什么是URL
URL的全称是统一资源定位符
通过一个URL可以找到互联网上唯一的一个资源
URL就是资源的地址、位置,互联网上的每个资源都有一个唯一的URL
URL的基本格式 = 协议://主机地址/路径
协议
: 不同的协议,代表着不同的资源查找方式、资源传输方式
主机地址
: 存放资源的主机(服务器)的IP地址(域名)
路径
: 资源在主机(服务器)中的具体位置
2. 什么是HTTP
HTTP的全称是Hypertext Transfer Protocol,超文本传输协议访问的是远程的网络资源,格式是http://
http协议是在网络开发中最常用的协议(其它:file(本地)、mailto(邮件)、FTP(共享))
特点
:简单,灵活,非持续连接
HTTP协议规定客户端和服务处之间的数据传输方式
让客户端和服务器能有效地进行数据沟通
二、Python中HTTP协议的使用
python中有一个第三方库requests,提供了所有和http协议相关的函数
1. get请求
get(url, params=None)
发送请求获取服务器返回的相应
url
: 请求地址,字符串
params
: 请求参数,字典
# 只适用于get请求
# url = 'https://www.apiopen.top/satinApi?type=1&page=1'
# response = requests.get(url)
# print(response) #
# 既适用于get也适用于post
url = 'https://www.apiopen.top/satinApi'
params = {'type': 1, 'page': 2}
response = requests.get(url, params)
print(response) #
2. 获取请求结果
1) 响应头
print(response.headers)
2) 响应体(数据)
a. 获取二进制对应的原数据
content = response.content
print(type(content)) #
b. 获取字符串类型的数据
text = response.text
print(type(text)) #
c. 获取json数据(json转换为python对应的数据)
json1 = response.json()
print(type(json1)) #
三、多线程基础
1. 进程
进程指的是在系统中正在运行的一个应用程序
特点
:每个进程之间是相互独立的,每个进程均运行在其专有且受保护的内存空间内
2. 线程
1) 什么是线程
程序运行的最小单元,一个进程(程序)的所有任务都在线程中执行
2)线程的串行
1个线程中任务的执行是串行的,同一时间1个线程只能执行1个任务
3)进程与线程的比较
a. 线程是CPU调度的最小单位
b. 进程是CPU分配资源和调用的单位
c. 一个程序可以对应多个进程,一个进程可以对应多个线程,但至少有一个线程
d. 同一个进程内的线程共享进程的资源
3. 多线程
1) 什么是多线程
1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务
多线程可以提高程序的执行效率
2)原理
实际上,在同一时间,CPU只能处理1条线程,即只有1条线程在工作(执行)
多线程并发执行,原理上是CPU快速地在多条线程之间调度(切换)
四、Python多线程的基础使用
1. 线程
每个进程中默认都有一条线程,即主线程;其它线程称为子线程
threading模块中Thread的对象就是线程对象,当程序中需要子线程时通过创建Thread对象即可
2. 多线程
1. 创建线程对象
Thread(target=None, args=()) : 创建并返回一个子线程对象
target
: 函数类型(function),在线程启动时这个函数会在子线程中执行
args
: 元组,元组中的元素是target对应的函数在子线程中调用的实参
2. 启动线程
线程对象.start() : 让线程去执行线程中的任务
def download(film_name: str):
print(film_name, threading.current_thread().name)
print('{}\t开始下载\t{}'.format(film_name, datetime.now()))
sleep(3)
print('{}\t下载结束\t{}'.format(film_name, datetime.now()))
def main():
# 单线程
# download('魔童降世')
# download('扫毒2')
# download('怦然心动')
pass
if __name__ == '__main__':
main()
# 多线程
# 1. 创建线程对象
"""
Thread(target=None, args=()) : 创建并返回一个子线程对象
target : 函数类型(function),在线程启动时这个函数会在子线程中执行
args : 元组,元组中的元素是target对应的函数在子线程中调用的实参
"""
t1 = threading.Thread(target=download, args=('魔童降世',))
t2 = threading.Thread(target=download, args=('扫毒2',))
t3 = threading.Thread(target=download, args=('怦然心动',))
# 2. 启动线程
"""
线程对象.start() : 让线程去执行线程中的任务
target(*args)
"""
t1.start()
t2.start()
t3.start()
3. 多线程2
1) 声明一个类继承Thread
2) 实现类中的run()方法,run()中的代码就是需要在子线程中执行的代码
3) 需要子线程时创建自己声明的线程类对象,并且不需要传任何参数
class DownloadThread(Thread):
def __init__(self, file_name):
super().__init__()
self.file_name = file_name
def run(self) -> None:
print(current_thread().name)
start = datetime.now()
print('{}\t开始下载\t{}'.format(self.file_name, start))
sleep(3)
end = datetime.now()
print('{}\t下载结束\t{}\t总用时:{}'.format(self.file_name, end, end - start))
def main():
t1 = DownloadThread('魔童降世')
t2 = DownloadThread('扫毒2')
t1.start()
t2.start()
if __name__ == '__main__':
main()
4. 程序结束
线程中的任务执行完成线程就结束;程序出现异常结束的是线程,而不是进程
进程中的所有线程都结束进程才结束
5. join()
线程对象.join() : 当前线程对象任务直线完成后才能直线后面的代码
def download(film_name: str) -> None:
start = time()
print('{}:{}\t开始下载'.format(current_thread().name, film_name))
sleep(randint(3, 6))
end = time()
print('{}\t下载结束\t总用时:{}s'.format(film_name, end - start))
def main():
# 1. join
"""
线程对象.join() : 当前线程对象任务直线完成后才能直线后面的代码
"""
t1 = Thread(target=download, args=('魔童降世',))
t2 = Thread(target=download, args=('扫毒2',))
t3 = Thread(target=download, args=('怦然心动',))
# 情况一:计算三部电影总用时
# start = time()
# t1.start()
# t2.start()
# t3.start()
# t1.join()
# t2.join()
# t3.join()
# end = time()
# print('三部电影总用时:{}s'.format(end - start))
# 情况二:电影1下载完成后才开始同时下载电影2和3
t1.start()
t1.join()
t2.start()
t3.start()
if __name__ == '__main__':
main()