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

这段时间学习了一个简单的爬虫项目,其中用到了多线程和生产者消费者模式,在这里总结下学习心得。

csdn表情包爬虫公开课链接

基础知识:

线程与进程:

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

并发与并行:

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

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

死锁条件:

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

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

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

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

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

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

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

生产者消费者模式:

爬虫初学-图片网站表情包爬虫_第1张图片
死锁:
死锁是指两个或两个以上的进程(线程)在运行过程中因争夺资源而造成的一种僵局(Deadly-Embrace) ) ,若无外力作用,这些进程(线程)都将无法向前推进。

项目:

环境:python3

生产者消费者设计模式:

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

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

代码:

'''
图片html示例:

吉祥物这个弟弟

吉祥物这个弟弟

'''
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()

你可能感兴趣的:(python,爬虫)