前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >妈妈再也不担心我没壁纸了!

妈妈再也不担心我没壁纸了!

作者头像
Python研究者
发布2020-10-29 16:54:21
3710
发布2020-10-29 16:54:21
举报
文章被收录于专栏:Python研究者

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

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

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

代码语言:javascript
复制
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/后面的数字就是代表页数,所以在最开始我们建立一个函数来存放我们需要的网页链接 如下:

代码语言:javascript
复制
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

代码语言:javascript
复制
import threading

首先建立一个glock 用来控制

代码语言:javascript
复制
gLock = threading.Lock()

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

代码语言:javascript
复制
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() #释放锁

消费者代码如下

代码语言:javascript
复制
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()

最后的代码就是启动线程

代码语言:javascript
复制
    for x in range(5):
        Generant().start()
    for x in range(5):
        Consumer().start()

观看运行结果

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

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

代码语言:javascript
复制
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()

正文结束!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python爬虫数据分析挖掘 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • python多线程爬取壁纸 妈妈再也不担心我没壁纸了!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档