用 Python 来爬取表情包

微信已经成为了我们大多数国人的聊天工具,在微信聊天中,选择合适的时机发送适当的表情,不仅可以丰富我们的聊天内容,而且还有化解尴尬、增进感情等等效果 。而后浪们还会经常开启战斗模式——斗图 。这时候谁的库存弹药充足谁就可获胜 。今天我就用 Python/ target=_blank class=infotextkey>Python 来爬取表情包,希望为各位后浪青年的聊天储备弹药,为增进后浪青年的交流略尽绵薄之力 。
选定目标【用 Python 来爬取表情包】既然是要抓取表情供后浪青年使用,那么我们就要选择后浪青年喜欢的表情社区作为目标,这里我把我那毒辣的眼神瞄向了“斗图啦”,网址是 https://www.doutula.com/ 。
我们进入网站
我们的目标是补充弹药库,所以我们需要关注网站的最新表情 。我选择爬取的模块是“最新表情”栏目
目标分析既然确定了目标,接下来我们就需要对目标页面进行分析,进而选择合适的爬取方式 。
获取页面内容我们首先可以看到这个页面是以分页的形式展现内容的,那么首先应该想到的是点击不同分页,看看 URL 是否是有规律的 。于是,我点击第二页,第三页,对应的 URL 分别是:
https://www.doutula.com/photo/list/?page=2 和 https://www.doutula.com/photo/list/?page=3 。这就好办了,除了第一页,其他的页面 URL 是根据分页数有规律变化的,那么我们就可以通过直接请求 URL 来获取每一页内容 。
解析页面内容解析页面内容获取到每一页的内容之后,我们就可以对每一页的网页内容进行解析了 。我们在页面点击右键,然后选择“显示源码”,来看看页面的源码是怎样的,从中找到解析内容的蛛丝马迹 。最简单的方法是从页面中找到一个图片的名称,去源码页面搜索,我搜索之后的结果是这样的:

用 Python 来爬取表情包

文章插图
 
我们很容易地看到每个图片都是一个 a 标签,从 a 标签中,我们可以获取到图片的 URL 以及图片的名称和后缀等信息 。
下载图片获取到图片的 URL 之后,我们只需要下载下来保存到本地目录就可以了 。
代码实现废话不多说,遵循目标分析的步骤,我直接将代码贴出来:
import threadingimport requestsfrom lxml import etreeimport osimport randomimport timefrom queue import Queueheaders = {'User-Agent': 'Mozilla/5.0 (windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/62.0.3202.94 Safari/537.36','cookie' : '你的cookie'}class Producer(threading.Thread):def __init__(self, page_queue, img_queue, *args, **kwargs):super(Producer, self).__init__(*args, **kwargs)self.page_queue = page_queueself.img_queue = img_queuedef run(self):while True:if self.page_queue.empty():break# 休息几秒钟time.sleep(random.randint(1, 3))url = self.page_queue.get()self.parse_page(url)def parse_page(self, url):response = requests.get(url, headers=headers)text = response.texthtml = etree.HTML(text)imgs = html.xpath("//div[@class='random_picture']//a//img")for img in imgs:# 过滤动图if img.get('class') == 'gif':continue# 获取图片urlimg_url = img.xpath(".//@data-backup")[0]if img_url.split('.')[-1] == 'gif':continue# 获取图片后缀suffix = os.path.splitext(img_url)[1]# 获取图片名称alt = img.xpath(".//@alt")[0]img_name = alt + suffixself.img_queue.put((img_url, img_name))class Consumer(threading.Thread):def __init__(self, page_queue, img_queue, *args, **kwargs):super(Consumer, self).__init__(*args, **kwargs)self.page_queue = page_queueself.img_queue = img_queuedef run(self):while True:if self.img_queue.empty() and self.page_queue.empty():returnimg = self.img_queue.get(block=True)url, filename = imgwith open("./images/"+filename, 'wb') as f:f.write(requests.get(url, timeout=30, headers=headers).content)f.close()print(filename + ' 下载完成!')def main():# url队列page_queue = Queue(15)img_queue = Queue(20)page_queue.put('https://www.doutula.com/photo/list/')for x in range(2, 6):url = "https://www.doutula.com/photo/list/?page={}" .format(str(x))page_queue.put(url)for x in range(6):t = Producer(page_queue, img_queue)t.start()for x in range(6):t = Consumer(page_queue, img_queue)t.start()if __name__ == '__main__':main()我们的代码中使用了生产者消费者模式,各自使用了队列来实现 。生产者不断从页面中获取图片链接,而消费者不断地下载这些获取到的图片到本地保存 。
我这里为了方便,只爬取了5页的图片 。运行代码(请将 cookie 改为你自己浏览器的 cookie),就会在代码同级目录下的 images 目录下生成图片了 。生成完成后的目录是这样的:


推荐阅读