目 录CONTENT

文章目录

Python爬虫入门_实战电影排行榜TOP50 爬取

小张的探险日记
2021-09-07 / 0 评论 / 0 点赞 / 618 阅读 / 2,704 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-09-07,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Python爬虫入门_实战电影排行榜TOP50 爬取


1.爬虫需求

​ 爬取 https://dianying.2345.com/top/ 电影排行榜 TOP50的电影信息

2.实现效果

​ 爬取的电影信息 写入 txt 文件,并把电影封面写入 frontCover 文件夹

image-20210509230558792

​ 爬取图片效果如下

image-20210509230652095

3.多线程(线程池)代码实现

​ 代码总体结构变化不大,主要 新增 MyThread类 继承了 threading.Thread ,并在 run 方法中 根据传入的 要下载的 list,调用了 download 方法。

​ 在 top50_list 方法中 开始调用 多线程,在此之前 把抓取到的 url 分成了 两份,起了两个子线程分别负责一份的下载。 不多说 多线程的机制了, 以后 有机会单独写一篇文章。

# 电影排行榜 TOP50 爬取 - 改造多线程(线程池)
import os
import time
from concurrent.futures import ThreadPoolExecutor

import requests
from bs4 import BeautifulSoup

url = 'https://dianying.2345.com/top/'


def top50_list(url):
    html = requests.get(url)
    # encoding是从http中的header中的charset字段中提取的编码方式,
    # 若header中没有charset字段则默认为ISO-8859-1编码模式,则无法解析中文,这是乱码的原因
    # html.encoding = html.apparent_encoding
    # 手动设置
    html.encoding = 'GBK'
    # print(html.encoding)
    # ISO-8859-1

    soup = BeautifulSoup(html.text, 'html.parser')
    li_list = soup.find(class_='picList clearfix').children
    li_one = []
    li_tow = []
    index = 0
    for li in li_list:
        if li.name == 'li':
            if index > 25:
                li_tow.append(li)
            else:
                li_one.append(li)
            index = index + 1
    # 声明线程池,并设置线程池的 最大线程数
    pool = ThreadPoolExecutor(5)

    # todo 此处特别注意 不能写成 download(li_one, '线程1')
    args1 = [li_one, '线程1']
    args2 = [li_tow, '线程2']
    # 通过submit函数提交执行的函数到线程池中,submit函数立即返回任务句柄,不阻塞
    t1 = pool.submit(lambda p: download(*p),args1)
    print('线程1创建完成' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    t2 = pool.submit(lambda p: download(*p),args2)
    print('线程2创建完成' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    # cancel方法用于取消某个任务,该任务没有放入线程池中才能取消成功
    # 这个任务 还在排队,没有被执行 就可以被 取消,如果在执行了 那么取消不了
    print(t1.cancel())
    # result方法可以获取task的执行结果,这个方法是阻塞的
    print(t1.result())
    # done方法用于判定某个任务是否完成
    print(t1.done())
    print(t2.done())

def download(li_list, name):
    if name =='线程1':
        time.sleep(1)
    movie_list = []
    for li in li_list:
        print('我是' + name)
        movie = {}
        # 电影名称
        movie['name'] = li.find(class_='sTit').text
        # 电影主演阵容
        star_list = li.find(class_='pActor').find_all('a')
        star_str = ''
        for star in star_list:
            star_str = star_str + (star.text + ',')
        movie['star'] = star_str
        # 电影描述
        movie['desc'] = li.find(class_='pTxt pIntroShow').text
        movie['pic'] = li.find(class_='pic').find('img')['src']
        movie_list.append(movie)

    # 写入文件
    with open('top50.txt', 'a+', encoding='utf-8') as f:
        for item in movie_list:
            f.write('电影名称:{} \t 主演阵容: {} \t {} \t 封面: {} \t \n'.format(
                item['name'], item['star'], item['desc'], item['pic']
            ))

    # 下载封面图
    for item in movie_list:
        result = requests.get('https:' + item['pic'])
        file_name = 'frontCover/' + item['name'] + '.jpg'
        if ':' in file_name:
            file_name = file_name.replace(':', '')

        os.makedirs(os.path.dirname(file_name), exist_ok=True)
        with open(file_name, 'wb') as f:
            f.write(result.content)

    if name == '线程1':
        print('线程1执行完成')
    else:
        print('线程2执行完成')

if __name__ == '__main__':
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    top50_list(url)
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))




适度放松,前路迷惘 停下来休息休息。 end

别人不会对你的痛感同身受,也没义务为你的过去买单,更不可能决定你的未来。

img

0

评论区