zoukankan      html  css  js  c++  java
  • 妈妈再也不担心我没壁纸了!

    python多线程爬取壁纸 妈妈再也不担心我没壁纸了!

    打开网站,这里我选择的是动漫专区的壁纸,我们的目的是把所有动漫壁纸爬下来,我们发现一共有98页图片


    所以我们要做的是观察每页图片链接的关系,我们打开第二页图片观察
    发现两页图片的链接分别是

    https://www.h128.com/pc/anime/0/2/1920x1080/t/1.html
    https://www.h128.com/pc/anime/0/2/1920x1080/t/2.html
    

    我们发现两个网页只有t/后面的数据不同由此我们观察后面几页,最终我们发现/t/后面的数字就是代表页数,所以在最开始我们建立一个函数来存放我们需要的网页链接
    如下:

    page_links_list = ['https://www.h128.com/pc/anime/0/2/1920x1080/t/1.html']
    def GetUrls(page_links_list):
        pages = int(input("请输入你想爬取的页数:"))
        if pages > 1:
            for page in range(2, pages + 1):
                url = 'https://www.h128.com/pc/anime/0/2/1920x1080/t/' + str(page) + '.html'
                page_links_list.append(url)
        else:
            page_links_list = page_links_list
    
    
    

    然后就是我们多线程的应用了,我们要用的是python的threading模块首先需要导入threading

    import threading
    
    
    

    首先建立一个glock 用来控制

    gLock = threading.Lock()
    
    
    

    **threading 提供了 Lock 类,该类能够在某个线程访问某个变量的时候对变量加锁,此时其它线程就不能访问该变量,直到该 Lock 被释放其它线程才能够访问该变量
    **
    我们爬虫需要生产者进程和消费者进程,生产者的线程专门用来生产一些数据,然后存放到一个中间的变量中。消费者再从这个中间的变量中取出数据进行消费。但是因为要使用中间变量,中间变量经常是一些全局变量,因此需要使用锁来保证数据完整性。在这个代码中生产者进程负责来获取我们图片的url,而消费者进程的目的是下载图片。
    生产者代码如下:

    class Generant(threading.Thread):
        def run(self):
            while len(page_links_list) > 0:
                gLock.acquire()  #上锁
                page_url = page_links_list.pop()
                gLock.release() #释放锁
                r = requests.get(page_url,headers = headers)
                r.raise_for_status()
                r.encoding = r.apparent_encoding
                a = re.findall('<img src="https:(.*?)" alt',r.text)
                gLock.acquire() #上锁
                for i in a :
                    x = 'https:' + i
                    x = x.replace('w_487', 'w_1421').replace('h_274', 'h_799')
                    img_links_list.append(x)
                gLock.release() #释放锁
    
    
    

    消费者代码如下

    class Consumer(threading.Thread,):
        def run(self):
            while True:
                gLock.acquire()
                if len(img_links_list) == 0:
                    gLock.release()
                    continue
                else:
                    img_url = img_links_list.pop()
                    gLock.release()
                    filename = img_url.split('?')[0].split('/')[-1]
                    r = requests.get(img_url)
                    print('正在下载:', filename)
                    path = './picture/' + filename
                    with open(path,'wb') as f:
                        f.write(r.content)
                        f.close()
                    if len(img_links_list) == 0:
                        end = time.time()
                        print("消耗的时间为:", (end - start))
                        exit()
    
    
    

    最后的代码就是启动线程

        for x in range(5):
            Generant().start()
        for x in range(5):
            Consumer().start()
    
    
    

    观看运行结果

    这里是下载了50页图片的时间,比起单线程还是很快的。

    最后附上完整代码
    下面展示一些 内联代码片

    import threading
    import requests
    import re
    import  time
    import  os
    page_links_list = ['https://www.h128.com/pc/anime/0/2/1920x1080/t/1.html']
    img_links_list = []
    headers = {
            "user-agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"
    }
    def GetUrls(page_links_list):
        pages = int(input("请输入你想爬取的页数:"))
        if pages > 1:
            for page in range(2, pages + 1):
                url = 'https://www.h128.com/pc/anime/0/2/1920x1080/t/' + str(page) + '.html'
                page_links_list.append(url)
        else:
            page_links_list = page_links_list
    gLock = threading.Lock()
    class Generant(threading.Thread):
        def run(self):
            while len(page_links_list) > 0:
                gLock.acquire()  #上锁
                page_url = page_links_list.pop()
                gLock.release() #释放锁
                r = requests.get(page_url,headers = headers)
                r.raise_for_status()
                r.encoding = r.apparent_encoding
                a = re.findall('<img src="https:(.*?)" alt',r.text)
                gLock.acquire() #上锁
                for i in a :
                    x = 'https:' + i
                    x = x.replace('w_487', 'w_1421').replace('h_274', 'h_799')
                    img_links_list.append(x)
                gLock.release() #释放锁
    class Consumer(threading.Thread,):
        def run(self):
            while True:
                gLock.acquire()
                if len(img_links_list) == 0:
                    gLock.release()
                    continue
                else:
                    img_url = img_links_list.pop()
                    gLock.release()
                    filename = img_url.split('?')[0].split('/')[-1]
                    r = requests.get(img_url)
                    print('正在下载:', filename)
                    path = './picture/' + filename
                    with open(path,'wb') as f:
                        f.write(r.content)
                        f.close()
                    if len(img_links_list) == 0:
                        end = time.time()
                        print("消耗的时间为:", (end - start))
                        exit()
    if __name__ == '__main__':
        GetUrls(page_links_list)
        if os.path.exists('./picture'):
            print("文件已存在")
        else:
            os.mkdir('./picture')
        start = time.time()
        for x in range(5):
            Generant().start()
        for x in range(5):
            Consumer().start()
    
    
    

    正文结束!!

    欢迎关注公众号:Python爬虫数据分析挖掘

    记录学习python的点点滴滴;

    回复【开源源码】免费获取更多开源项目源码;

    公众号每日更新python知识和【免费】工具;

    本文已同步到【开源中国】、【腾讯云社区】、【CSDN】;

    耐得住寂寞,才能登得顶
    Gitee码云:https://gitee.com/lyc96/projects
  • 相关阅读:
    01背包回溯法
    网络嗅探器
    侦听局域网内密码
    Winsock协议目录
    LSP(分层服务提供者)
    n后问题回溯法
    批处理作业调度回溯法
    图m着色问题
    SPI概述
    符号三角形问题回溯法
  • 原文地址:https://www.cnblogs.com/chenlove/p/14038555.html
Copyright © 2011-2022 走看看