Python Day7 爬虫-线程池和指令系统

6 篇文章 1 订阅
1 篇文章 0 订阅

Day7 线程池和指令系统

1. 线程等待(阻塞)

# 引入模块
from threading import Thread
from time import sleep
from datetime import datetime
from random import randint


def download(name):
    print(f'{name}开始下载:{datetime.now()}')
    sleep(randint(2, 7))
    print(f'{name}下载结束:{datetime.now()}')


if __name__ == '__main__':

    t1 = Thread(target=download, args=('明日战纪',))
    t2 = Thread(target=download, args=('斗罗大陆',))
    t3 = Thread(target=download, args=('独行月球',))

    # 示例1:三个电影都下载结束后打印“全部下载完成”
    t1.start()
    t2.start()
    t3.start()

    # 1. 子线程对象.join()  -  阻塞当前线程直到指定子线程任务完成
    t1.join()
    t2.join()
    t3.join()
    print('-------------全部打印完成--------------')

    # 示例2:前两个电影下载完成后才下载第三个电影
    t1.start()
    t2.start()

    t1.join()
    t2.join()

    t3.start()

2. 线程池

'''
Author:KathAmy
Date:2022/8/19  10:13
键盘敲烂,共同进步!
'''

# 1.线程池  -
'''
线程池的工作原理:先创建指定个数的线程,然后添加多个任务(任务数量>线程数量),
              让线程池中的线程去执行添加的所有任务,知道所有任务都执行完(线程池中的每个线程可能会执行多个任务)
'''

from threading import Thread, current_thread
from time import sleep
from datetime import datetime
from random import randint
from concurrent.futures import ThreadPoolExecutor



def download(name):
    print(f'{name}开始下载:{datetime.now()}', current_thread())
    sleep(randint(2, 7))
    print(f'{name}下载结束:{datetime.now()}')


if __name__ == '__main__':
    # 方案1:直接使用多线程下载1000个电影
    num = 0
    for _ in range(10):
        ts = []
        for x in range(100):
            num += 1
            t = Thread(target=download, args=(f'电影{num}',))
            ts.append(t)
            t.start()
        for x in ts:
            x.join()

    # 方案2:使用线程池下载1000个电影
    # 1.创建线程池
    # ThreadPoolExecutor(线程数最大值)
    pool = ThreadPoolExecutor(3)

    # 2.添加任务
    # 1)一次添加一个任务:submit(函数, 实参1, 实参2, 实参3, ...)
    # 注意:实参的数量有前面的函数在调用的时候需要的实参来决定
    pool.submit(download, '肖生克的救赎')
    pool.submit(download, '霸王别姬')

    # 2)同时添加多个任务:map(函数, 参数对应的序列)
    # 注意:使用map添加多个任务的时候,任务对应的函数必须是有且只有一个参数的函数
    pool.map(download, ['冰雪奇缘', '海蒂', '一起老去'])

    # 3.关闭线程池
    # 线程池关闭后无法再添加新的任务,并且会阻塞当前线程等待整个线程池的任务都完成
    pool.shutdown()
    print('完成啦!')

3. 线程爬某瓣电影

'''
Author:KathAmy
Date:2022/8/19  17:33
键盘敲烂,共同进步!
'''
import requests
from bs4 import BeautifulSoup
import csv
from concurrent.futures import ThreadPoolExecutor


def get_net_data(url: str):
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
    }
    proxies = {
        'http': '121.206.253.171:4512',
        'https': '121.206.253.171:4512'
    }
    response = requests.get(url, headers=headers, proxies=proxies)
    # return response.text
    analysis_data(response.text)


def analysis_data(html: str):
    # 解析数据
    soup = BeautifulSoup(html, 'lxml')
    all_film_div = soup.select('.grid_view>li>.item')
    all_data = []       # 保存每一页所有的电影
    for div in all_film_div:
        rank = div.select_one('.pic>em').text
        name = div.select_one('.title').text
        info = div.select_one('.bd>p').text.strip().split('\n')[-1].strip()
        # time, country, category = info.split('/')
        info_list = info.split('/')
        time = info_list[0]
        country = info_list[-2]
        category = info_list[-1]
        score = div.select_one('.rating_num').text
        comment_count = div.select('.star>span')[-1].text[:-3]
        intro_span = div.select_one('.inq')
        if intro_span:
            intro = intro_span.text
        else:
            intro = ''
        all_data.append([int(rank), name, score, time.strip(), country.strip(), category.strip(), comment_count, intro])

    films.append(all_data)


if __name__ == '__main__':
    films = []      # 保存整个网站所有的电影
    # [
    #     [[26, ], [], [], ...],
    #     [[1], [], [],  ...],
    #     [[23], [], [], ...],
    # ]
    f = open('电影.csv', 'w', encoding='utf-8', newline='')
    writer = csv.writer(f)
    writer.writerow(['排名', '电影名称', '评分', '上映时间', '国家', '类型', '评论数', '简介'])

    pool = ThreadPoolExecutor(10)
    for page in range(0, 251, 25):
        url = f'https://movie.douban.com/top250?start={page}&filter='
        pool.submit(get_net_data, url)

    pool.shutdown()
    # 优化方案:按页排序
    films.sort()
    for x in films:
        writer.writerows(x)

4. 某瓣电影多线程下载数据

'''
Author:KathAmy
Date:2022/8/19  17:37
键盘敲烂,共同进步!
'''
import requests
import csv
from bs4 import BeautifulSoup
from threading import Thread
from datetime import datetime

f = open('多线程豆瓣.csv', 'a', encoding='utf-8', newline='')
writer = csv.writer(f)
writer.writerow(['名字', '分数', '评论人数', '介绍'])


def get_html(url):
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36'
    }
    response = requests.get(url=url, headers=headers)
    return response.text


def download(page, url: str):
    print(f'第{page}页开始下载:{datetime.now()}')
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    all_li = soup.select('.grid_view>li')
    new_list = []
    for li in all_li:
        name = li.select_one('.item>.info>.hd .title').text
        scores = li.select_one('.bd>.star>.rating_num').text
        numbers = li.select_one('.item>.info>.bd>.star>span:nth-child(4)').text
        info = li.select_one('.bd>.quote')
        if info:
            info = li.select_one('.bd>.quote').text.strip()
        else:
            info=''
        new_list.append([name, scores, numbers, info])
    print(new_list)
    writer.writerows(new_list)

    print(f'第{page}页下载完成:{datetime.now()}')


if __name__ == '__main__':
    ts = []
    for i in range(0, 51, 25):
        url = f'https://movie.douban.com/top250?start={i}&filter='
        t = Thread(target=download, args=(i, url))
        ts.append(t)
        t.start()


    # 等待所有的子线程任务都结束后再接着执行
    for x in ts:
        x.join()
    f.close()

5. 常用指令操作

执行指令的工具: Windows - 命令提示符(cmd) 、Mac - 终端

5.1 运行python程序

运算程序的计算机必须先安装python环境

win:    python  py文件路径     
mac:  python3  py文件路径     

5. 2 进入文件夹: cd

 cd  文件夹相对路径、文件夹绝对路径

注意:如果是windows操作系统,cd操作如果要跨盘需要先切盘,然后再cd
	   切盘方法:C:、E:、D:

5.3 查看当前文件夹的内容

win:  dir
Mac:ls

5.4 用指令创建虚拟环境

 第一步:找到一个用来放虚拟环境的文件夹
 第二步:通过cd指令进入到存放虚拟环境的文件夹中

 第三步:创建虚拟环境
		   python    -m    venv    虚拟环境名
		   python3    -m   venv   虚拟环境名

 第四步:激活虚拟环境
		  (mac) source  虚拟环境目录/bin/activate
		  (windows)  虚拟环境目录\ Scripts\activate.bat

第五步:退出虚拟环境
			deactivate

5.5 常用pip指令

(pip - Python包管理工具)
pip list - 查看当前环境已经安装过的所有的第三方库

pip install  第三方库名称		-		下载并且安装指定的第三方库
pip install  第三方库名称 -i 镜像地址		-		在指定的镜像地址中下载安装
pip install  第三方库名称==版本号	-i   镜像地址

pip install  第三方库名称1   第三方库名称2  

pip freeze > 依赖文件名  	-	生成依赖文件	
pip install -r 依赖文件路径			-		批量安装	

pip uninstall 第三方库名称   -  卸载指定的第三方库
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值