爬虫初学-图片网站表情包爬虫

这篇博客记录了作者学习Python爬虫的过程,重点介绍了如何使用多线程和生产者消费者模式来爬取图片网站的表情包。文中详细讲解了线程与进程、并发与并行、死锁条件以及生产者消费者模式的基础知识,并概述了爬虫项目的基本流程,包括请求数据、解析数据和保存数据的步骤。
摘要由CSDN通过智能技术生成
这段时间学习了一个简单的爬虫项目,其中用到了多线程和生产者消费者模式,在这里总结下学习心得。

csdn表情包爬虫公开课链接

基础知识:

线程与进程:

进程是操作系统分配资源的最小单元, 线程是操作系统调度的最小单元。
一个应用程序至少包括1个进程,而1个进程包括1个或多个线程,线程的尺度更小。
每个进程在执行过程中拥有独立的内存单元,而一个线程的多个线程在执行过程中共享内存

并发与并行:

并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。

并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。

死锁条件:

产生死锁的四个必要条件:

1 互斥条件:
进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。

2 不可剥夺条件:
进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。

3 请求与保持条件:
进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

4 循环等待条件:
存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被链中下一个进程所请求。

资源分配图含圈而系统又不一定有死锁的原因是同类资源数大于1。但若系统中每类资 源都只有一个资源,则资源分配图含圈就变成了系统出现死锁的充分必要条件。

只要上述条件之一不满足,就不会发生死锁。

生产者消费者模式:

在这里插入图片描述
死锁:
死锁是指两个或两个以上的进程(线程)在运行过程中因争夺资源而造成的一种僵局(Deadly-Embrace) ) ,若无外力作用,这些进程(线程)都将无法向前推进。

项目:

环境:python3
生产者消费者设计模式:

生产者:专门用来获取表情包url链接
消费者:从链接中下载图片
全局变量:表情报链接列表

爬虫的流程分析:
  1. 请求数据:requests库(这个库可以非常方便的去请求网络数据)
    • 安装方法:pip install requests
  2. 将请求下来的数据解析出来,获取我们想要的数据,把不想要的数据抛弃掉。
    • BeautifulSoup:pip install bs4
    • lxml:pip install lxml
  3. 将解析后的数据保存下来。如果是文字类型的,可以保存到文件中或者是数据库中或者缓存中都可以。如果是文件类型,比如图片,视频,那么可以保存到硬盘中。

代码:

'''
图片html示例:
<a class="col-xs-6 col-sm-3" href="http://www.doutula.com/photo/2250142" style="padding:5px;">
<img referrerpolicy="no-referrer" src="//static.doutula.com/img/loader.gif?32" data-original="http://ww1.sinaimg.cn/bmiddle/9150e4e5gy1g6c23kx7dfj203p03p3yc.jpg" alt="吉祥物这个弟弟" class="img-responsive lazy image_dta" data-backup="http://img.doutula.com/production/uploads/image/2019/08/25/20190825729166_CJvrVi.jpg">
<p style="display: none">吉祥物这个弟弟</p>
</a>

'''
from bs4 import BeautifulSoup
import requests
from urllib import request
import os
import threading

#全局变量
PAGE_URLS = []
IMG_URLS = []

gLock = threading.Lock()

#伪装头部,从谷歌浏览器获取
headers = {
        "User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36"
        }

#生产者
def producer():
    while True:
        gLock.acquire()
        if len(PAGE_URLS) == 0:
            gLock.release()
            break
        #pop出列表最后一个元素
        page_url = PAGE_URLS.pop()
        gLock.release()
        
        #2. 对请求身份进行伪装,使用lxml库解析html文件
        response = requests.get(page_url,headers=headers)
        text = response.text
        soup = BeautifulSoup(text,'lxml')
        
         #3.找到图片class->找到图片url(参考图片html示例)
        img_list = soup.find_all("img",attrs={"class":"img-responsive lazy image_dta"})
        for img in img_list:
            img_url = img['data-original']
            IMG_URLS.append(img_url)

 #消费者           
def consumer():
    while True:
        gLock.acquire()
        if len(PAGE_URLS) == 0 and len(IMG_URLS) == 0:
            gLock.release()
            break
        
        if len(IMG_URLS)>0:
            img_url = IMG_URLS.pop()
        else:
            img_url = ''
        gLock.release()
        
        #windows‘\‘ mac/Linux’/‘ 跨平台表示法os.path.join
        #[-1]表示最后一个元素
        #4.将解析后的数据保存到img文件下
        if(img_url):
            filename = img_url.split("/")[-1]
            fullpath = os.path.join("img",filename)
            request.urlretrieve(img_url,fullpath)
            print("%sDownload Success"%filename)

def main():
    # 1. 将每一页的url存到PAGE_URLS数组里
    for x in range(1,100):
        page_url = "http://www.doutula.com/photo/list/?page="+str(x)
        PAGE_URLS.append(page_url)
    
    for x in range(5):
        th = threading.Thread(target = producer)
        th.start()
        
    for x in range(5):
        th = threading.Thread(target = consumer)
        th.start()
            
if __name__ == '__main__':
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值