08多任务爬虫

多任务爬虫

线程进程回顾

实现多任务爬虫的方式:多进程/多线程

进程:是计算机当中最小的资源分配单位

线程:是计算机当中可以被CPU调度的最小单位

我们执行一个python代码的时候,在计算机的内部会创建一个进程,在进程当中会创建一个线程,代码是由线程去执行的

创建进程/线程

import time
from multiprocessing import Process


# 1. 将需要子进程执行的事情写在一个函数里面
def func1():
    print('开始执行')
    time.sleep(3)
    print('执行结束')

if __name__ == '__main__':
    # 2. 通过Process类创建一个进程对象 关联函数
    p1 = Process(target=func1)
    # 3. 通过进程对象调用start方法
    p1.start()
class MyProcess(Process):
    def __init__(self, value):
        super(MyProcess, self).__init__()
        self.value = value

    def run(self):
        print('开始执行')
        print(self.value)
        time.sleep(3)
        print('执行结束')
        
        
if __name__ == '__main__':
    p1 = MyProcess("jcx")
    p1.start()

进程特点

  • 我们开启的进程是原来进程的子进程,子进程复制父进程全部的代码
  • 子进程只运行target函数,其他的都是父进程执行的内容,但是子进程也有父进程有的资源
  • 进程之间执行互不影响,也没有先后顺序
  • 一个进程中所有线程是共享进程资源的

GIL:全局解释器锁

  • GIL是cpython特点 而不是python的特点
  • 我们安装python都是cpython版本
  • 要一个进程在同一时刻是有一个线程能被cpu调用
  • 如果要想使用计算机的多核优势的话 我们就要使用进程
  • 如果不需要使用计算机的多核优势的话 我们就要使用线程

lol英雄皮肤

import os

import requests
from concurrent.futures import ThreadPoolExecutor


class LOLImageSpider:
    def __init__(self):
        self.hero_list_url = 'https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js?ts=2795830'
        self.hero_info_url = 'https://game.gtimg.cn/images/lol/act/img/js/hero/{}.js?ts=2795830'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; Tablet PC 2.0; .NET4.0E)'
        }
        self.pool = ThreadPoolExecutor(10)

    def get_hero_url(self, url):
        """获取到英雄id,获取到英雄皮肤的url"""
        json_data = requests.get(url, headers=self.headers).json()

        hero_list = json_data['hero']

        for hero in hero_list:
            hero_id = hero['heroId']
            info_url = self.hero_info_url.format(hero_id)
            response = requests.get(info_url, headers=self.headers).json()
            self.parse_data(response)

    def parse_data(self, response):
        """获取图片链接"""
        skins_list = response["skins"]
        for skins in skins_list:
            name = skins['name']
            main_img = skins['mainImg']
            if main_img:
                self.pool.submit(self.save, name, main_img)

    def save(self, name, main_img):
        """图片存储的方法"""
        img = requests.get(main_img, headers=self.headers).content
        filename = 'lol1'
        # 如果当前文件同级的目录下 没有一个文件夹叫lol
        if not os.path.exists(filename):
            # 帮我们创建这个文件夹
            os.mkdir(filename)

        # lol/xx.jpg
        with open(filename + f"/{name.replace('/', '')}.jpg", 'wb')as f:
            f.write(img)
        print(name, main_img)

    def run(self):
        self.get_hero_url(self.hero_list_url)


if __name__ == '__main__':
    spider = LOLImageSpider()
    spider.run()
posted @ 2023-04-05 00:48  LePenseur  阅读(16)  评论(0编辑  收藏  举报