之前有介绍过GitHub上的表情包仓库,但感觉数量太少,不能满足经常斗图的需求,于是我决定从无所不有的互联网中挖掘表情包资源。只要表情包的小伙伴拉到底下传送门直达哟!

 

来斗图吧 骚年!_python

 

这次的爬取目标是人均年薪百万的某乎,里面有关表情包的问答,几乎每个回答都给出了大量的表情包,来自五湖四海的网友在某乎以表情包会友,那我就来把你们发的全部都收集起来~

 

来斗图吧 骚年!_python_02

 

首先我们先把所有回答展开,查看全部回答。打开开发者工具,找到回答所在页面,将Requests Headers里的内容全部拷贝到咱们自己的Headers中。利用 requests 爬取该页面。

 

params 中的 offset 根据页面的更改更改其值,每翻一页,offset 就加5 。其他的参数不发生改变。

 

接着观察网页源代码,我们可以清楚的看到每一张图片的链接就放在  data-actualsrc 之后。

 

来斗图吧 骚年!_python_03

 

而这个链接的获取可以使用正则表达式将其从网页源代码中获取。

 

  •  
pic_urls=re.findall(r'data-actualsrc="(.*?.(gif|jpg|png))',content)

 

根据这些图片的url链接,我们只要再构造requests请求,便可以把所有图片下载下来。一个很直观的想法就是先访问源网页,用一个列表保存所有的图片url,然后遍历这个列表,逐个访问并下载内容。

 

这样操作的话消耗的内存比较大,并且下载图片的速度较慢,因此我采取了另外一种策略,一个简单的 Requests + Redis 的分布式爬虫。

 

来斗图吧 骚年!_python_04

 

获取图片URL

 

按照之前所说的那样,爬取获得URL链接,不同的是,我们将其存储在Redis中把所有 url 添加到同一个集合中。

 

  •  
def get_urls(self,offset,urls):             params={                'include': 'data[*].is_normal,admin_closed_comment,reward_info,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,created_time,updated_time,review_info,relevant_info,question,excerpt,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,is_labeled,is_recognized,paid_info,paid_info_content;data[*].mark_infos[*].url;data[*].author.follower_count,badge[*].topics',                'limit': 5,                'offset': offset,                'platform': 'desktop',                'sort_by': 'default'                              }        r=requests.get(self.url,headers=self.headers,params=params)        data=r.json()['data']        for i in data:            content=i['content']            pic_urls=re.findall(r'data-actualsrc="(.*?.(gif|jpg|png))',content)            for j in range(len(pic_urls)):                self.r.sadd("urls",pic_urls[j][0])

 

来斗图吧 骚年!_python_05

 

图片下载

 

新建一个py文件用于下载图片,因为链接的获取速度比图片下载速度快不少,因此在图片下载这一环中采用了多线程处理 requests 请求。

 

  •  
    def download(self):        if "urls" in self.r.keys():            while True:                try:                    url=self.r.spop("urls")                    r=requests.get(url,headers=self.headers)                    with open(img_path+os.path.sep+'{}{}'.format(self.count,url[-4:]),'wb') as f:                        f.write(r.content)                                        print("已经成功下载{}张表情包!".format(self.count))                    self.count+=1                except:                    if "urls" not in self.r.keys():                        print("表情包已全部下载完成")                        break                    else:                        print("{}请求发送失败!".format(url))                        continue        else:            self.download(self)

 

两个程序同时运行,一边获取url存入Redis, 另一边提取url 下载图片。大大加快了下载速度,并且减少了内存的使用。

 

成果展示

 

一共爬取了5W+张表情包,包含骚骚的gif动图。哈哈!斗胆问一句:斗图谁与争锋?

 

来斗图吧 骚年!_python_06

 

 

来斗图吧 骚年!_python_07

往期精彩

 

Python自动刷网课

学计算机的男生发这个给我看是什么意思?

疯狂的声音,有趣的排序