源码日后博客分享
需求分析:
-
背景:机器视觉模型的训练需要大量的图像数据,而互联网上充斥着大量的图像数据,但是并不是所有数据能满足模型数据,这次我们需要满足人脸识别模型的要求,也就是需要大量含有人脸的图像。所以在“嘈杂”的数据环境中,去爬取到符合标准的数据,这也是我们最基本的目标。
-
由于互联网上公开图片的地方很多,但是我们需要的大量的图片(百万级上),所以满足标准的平台就很有限,我们将目标集中在社交网络、新闻网站、图片分享网站等等。
-
现在的网站都是采用HTML5和JS动态渲染,而且关于网页上的各种数据请求都会通过JS加密校验参数,直接对请求头进行分析稍显复杂,所以现存的爬虫框架在对付这些问题时可能会有些吃力。所以我们需要针对不同的网站进行定制化编写爬虫。
-
爬取的图片数据纷繁复杂,为满足模型需要,我们需要进行初步筛选,包括去重、分辨率、内存大小、图片比例等等,但是最为重要的就是需要筛选出含有人脸的图片。好在中国互联网环境良好,其中佼佼者提供了质量可观的开放API【Face++、百度AI 等】。
-
最终需要存储这些数据,这只是单纯的下载策略问题。
设计原则:
-
将代码分成三个模块爬虫、筛选、下载,各个模块通过图片URL通信
-
关于爬虫模块,我们想要只需要根据各个网站不同特点设计爬虫,形成爬虫群,然后把获取的URL送个接口就可以了
-
关于过滤模块,我们需要将爬取来的URL进行有效的识别,这完全可交给这些大佬公开的API,而我们需要做的就是进行速度的匹配,因为过滤相模块当于工厂里的一条传送带,我们需要把生产速度(爬虫)和出货速度(下载)进行匹配,以防生产过剩或者供应不足。
-
关于下载模块,我们需要做的就是变换下载方式,以提高下载效率,例如多线程下载。
-
细枝末节:接口间的高并发操作,IP检测,账号封号,开放平台QPS限制,日志记录,外部属性可配置,减少重复编程,减少代码修改频率等等
-
综上所述,我们需要尽可能按照软件工程学的流程进行开发,提高代码的质量和可维护性,减少模块间的耦合度,以及可以长时间无监督稳定运行。
设计思路:
-
对于JS进行动态渲染的网站,采用Selenium+Chrome+ChromeDriver的策略来结局,而关于过滤器部分,直接下载他们的开发版本再自己设计成只接受URL的接口。
-
各个模块之间通过读取和写入同一文件来实现通信,并且需要设计互斥锁来控制并发冲突。
-
所有的Spider应该向同一文件(Unfiltered_URL.txt)写入URL,一共Filter进行过滤【注意:考虑写冲突,并且应加入标识以区分(供Filter区分)】
-
Filter应向Downloader提供唯一的下载列表(Filtered_URL.txt)。
-
同一时间内应该有多只爬虫(Spider)同是在对相同网站或不同网站进行并行爬取,所以在进行保存成果时应该考虑并发,并且遵守统一的标准,因此考虑使用继承。
-
在有大量URL数据时,过滤器(Filter)也应该相应提高吞吐量,而各大开放平台对QPS又有不同程度的限制,所以要为每个不同的Filter提供不同的识别码。
-
在有新的数据源爬虫加入时,应该是动态的增加,也就是说:不需要暂停已经运行的系统,直接增加爬虫就可以完成任务。(可动态扩展)
-
为了检测各个模块的吞吐量和系统效率,防止出现数据拥堵,我们必须要可以设计出可以衡量的数据展示方式。我们可以这样解决:在处理数据的同时进行数据的搬运(处理包括过滤、下载),将经过处理的数据搬运到新的文件里(也就是History_Download_URL.txt、History_Unfiltered_URL.txt)。
-
由于该系统将要在长时间无监督情况下运行,所以我们必须建立完备的日志系统。
-
另外,此系统涉及大量的文件操作,每只Spider都有自己独立的配置文件,Filter和Downloader更不用提,所以如果将路径存在对应的配置文件中再好不过。
文件结构:
爬虫模块:
【注】本项目涉及大量不同种类爬虫,而爬虫的逻辑和源码又是大家最为关心的问题,我后续将逐个发表各爬虫的设计逻辑和部分源码。
接下来简要分析一下新浪微博(Web)爬虫:
Problem List:
-
当前版本的微博如果不登录是没办法查看内容的,当然也没办法爬数据了。所以第一步需要解决登录问题。
-
据我个人经验,微博的登录时效是24小时,所以持久化Cookies成了和登录并驾齐驱的问题。
-
我们需要爬的时图片,策略一:爬动态配图,策略二:爬相册,我选择后者。
-
相册的入口是单个的用户,所以获取用户的问题也十分重要。
-
在爬虫方面,我这人十分贪婪,我的目标是全网用户,所以构建关系网RelationNet同样需要关注。
难点分析:(本人实践所得)
-
微博登录如果使用帐号直接登录,将会遇到图形验证码,策略一:识别验证码,策略二:绕过。
-
在使用模拟登录时,微博官方会直接返回游客页面,容易报TimeOut,策略:加入cookies后从其他站点跳转。
-
直接构造请求然后通过get或者post请求数据时,微博会直接返回一个带JS的页面,不论我们怎么请求,返回的结果都是大同小异,经我查看,返回的JS时用来重新请求我们所发出的请求,很是讽刺,策略:此路不通。
-
微博对爬虫的检测并不是很敏感,但也不是没有防备,我在一分钟内连续请求超过7k+张图片,直接报414,IP地址被封了大概十分钟左右,策略:每次请求间隔0.2s(经验值)
-
微博对于RelationNet的生成有一定限制,所能快速确认的关联用户个数<200个/用户。
逻辑图:
关系网络:
过滤器模块:
整体流程:
Face++流程:
Face++文件结构:
下载器模块: