您的位置:首页 > 其它

爬虫笔记——多线程爬取斗图网表情包(threading)

2019-07-22 22:38 78 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/wang_zuel/article/details/96890756

爬虫笔记——多线程爬取斗图网表情包(threading)

斗图网网址:斗图网,这里以爬取最新套图为例。

网站观察

在网页翻页操作中可以看到网页是非动态加载的(page为页码),那么通过requests方式爬取要更为快捷。

可以看到每个套图都在分别不同的框中,那么首先就要爬取每个套图的具体链接。

通过检查(f12)可以发现每个套图的链接地址

在每个具体链接中又可以得到具体的套图表情包

同样可以得到每个图片的下载链接

爬取框架

综上分析,可将具体的爬取过程分为:获取每个套图的链接 > 获取每个表情的链接 > 下载,而对于要下载的图片,若此处一个一个下载,则会耗时极长,故此处选择多线程方式进行爬取。

具体代码

import requests
import threading
import time
import os
import re
from urllib import request
from lxml import etree
from queue import Queue

# 生产者类用于爬取表情包链接
class Producer(threading.Thread):

HEADERS = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
}

def __init__(self,page_queue,img_queue,*args,**kwargs):
super(Producer,self).__init__(*args,**kwargs)
self.page_queue = page_queue
self.img_queue = img_queue

def run(self):
while True:
if self.page_queue.empty():
print("=="*20)
break
url = self.page_queue.get()
self.parse_taotu_links(url)

# 套图链接爬取
def parse_taotu_links(self,link):
resp = requests.get(link,headers=self.HEADERS)
text = resp.text
html = etree.HTML(text)
bqb_links = html.xpath('//div[@class="col-sm-9 center-wrap"]/a/@href')
for link in bqb_links:
self.parse_img_links(link)

# 表情包链接爬取
def parse_img_links(self,link):
resp = requests.get(link,headers=self.HEADERS)
text = resp.text
html = etree.HTML(text)
img_titles = html.xpath('//li[@class="list-group-item"]//div[@class="pic-content"]//img/@alt')
img_links = html.xpath('//li[@class="list-group-item"]//div[@class="pic-content"]//img/@src')
for img_title,img_link in list(zip(img_titles,img_links)):
# 去除文件名当中的特殊符号
img_title = re.sub(r'[.。*??!!@]','',img_title)
# 为文件名加上后缀,后缀在表情包链接当中,为链接的后缀
suffix = os.path.splitext(img_link)[1]
# 去除后缀当中的特殊字符串
suffix = re.sub(r'!dta','',suffix)
img_title = img_title + suffix
self.img_queue.put((img_title,img_link))

# 消费者类线程用于下载
class Consumer(threading.Thread):
def __init__(self,page_queue,img_queue,*args,**kwargs):
super(Consumer,self).__init__(*args,**kwargs)
self.page_queue = page_queue
self.img_queue = img_queue

# 下载表情包
def run(self):
# 计算一下程序运行时间
start = time.clock()
# 这里先暂停一秒,让生产者部分先爬取链接,不然会出现一开始就结束循环的情况
time.sleep(1)
while True:
if self.page_queue.empty() and self.img_queue.empty():
end = time.clock()
t = end - start
print("所有表情包下载完成!")
print("下载共花费时间%.1f分钟"%(t/60))
break
img_title,img_link = self.img_queue.get()
request.urlretrieve(img_link,'C:/Users/123/Desktop/bqb/taotu/'+img_title)
print(img_title+"       下载完成!")

def main():
# 网页队列(这里为了方便只爬取30页内容,可以自己设定)
page_queue = Queue(100)
# 表情包队列
img_queue = Queue(100)

for page in range(1,11):
url = 'https://www.doutula.com/article/list/?page=%d'%page
# 将网址放到page_queue队列中
page_queue.put(url)

# 定义5个爬取表情包链接的线程
for producers in range(5):
t = Producer(page_queue,img_queue)
t.start()

# 定义5个下载表情包的线程
for consumers in range(5):
t = Consumer(page_queue,img_queue)
t.start()

main()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: