1. 背景
金融大数据智能采集,结合AI,自主研发智能爬虫技术,大规模爬取互联网各行各业的数据,极其丰富的数据源,结合自身内部数据,分析挖掘,提取有价值的信息,为金融中心资金管理、风险控制、经营状况、市场策划及营销活动等提供有效的解决方案,同时提供最新的金融行业资讯,始终与时俱进,最终达到数据驱动决策,实现智能数据化运营。
2.系统架构
2.1 核心架构
四个组件:Downloader、PageProcessor、Scheduler、Pipeline
参考scrapy/webmagic框架,简化的整体架构如下:
下载器
下载器负责从互联网上下载页面以供后续处理,默认使用Apache HttpClient作为下载工具。
页面处理器
PageProcessor负责解析页面,提取有用信息,发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并在此基础上开发了解析XPath的工具Xsoup。
在这四个组件中,PageProcessor对于每个站点、每个页面来说都是不同的,是需要用户定制的部分。
调度器
Scheduler 负责管理需要爬取的 URL 以及一些去重工作,默认提供了 JDK 内存队列来管理 URL,使用 collection 来去重,同时支持使用 Redis 进行分布式管理。
除非你的项目有一些特殊的分布式需求,否则没必要自己定制Scheduler。
管道
Pipeline负责对抽取的结果进行处理,包括计算、持久化到文件、数据库、HDFS、ES等。默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。
Pipeline 定义了结果如何保存,如果要保存到特定的数据库,需要写一个对应的 Pipeline,针对某一类需求,只需要写一个 Pipeline 即可。
2.2 功能模块
基于Redis的分布式爬虫系统
爬虫框架采用Scrapy,通过scrapy_redis和Redis实现分发。
在分布式系统中,一台机器充当Master,安装Redis进行任务调度。其他机器充当Slaver,只从Master那里拿任务去爬取。其原理是:Slaver运行时,scrapy遇到请求时,不交给spider去爬取,而是统一交给Master机器上的Redis数据库去处理。spider想要爬取的请求也是从Redis那里拿,Redis收到请求后,先去重,然后存入数据库,再交给需要该请求的Slaver,从而实现任务协调。
Redis
Redis 是一个开源(BSD 许可)的内存数据结构存储系统,可用作数据库、缓存和消息中间件。它支持多种类型的数据结构,例如字符串、哈希、列表、集合、具有范围查询的有序集合、位图、超日志和地理空间索引半径查询。
与Redis类似的还有Memcached,同样是基于内存的高性能缓存数据库。Redis是单线程模型,而Memcached支持多线程;但是Memcached只支持Key-Value存储,而Redis支持多种数据结构,这也是本文选择Redis的原因之一。
Redis 虽然是单线程模型,但其性能远超我们业务的需求,单机 Redis 的读写速度最高可达 10 万次/秒。利用 Redis 的列表数据结构,可以实现发布订阅模型或者类似消息队列的功能。不过与 MQ、Kafka 等消息队列不同,Redis 是一个高性能的消息队列,实时性很高。
Scrapy实现分发
Scrapy-redis
Github上有个项目叫scrapy-redis,通过Redis实现分布式爬虫。Scrapy原生的任务调度是基于文件系统的,通过JOBDIR指定存储任务信息的路径,这样爬虫就只能在单机上进行。scrapy-redis通过修改Scheduler、Item Pipeline等组件,将任务、数据信息的存储和访问放到redis的queue中,这样就可以多台服务器同时执行爬虫和items流程,大大提高数据爬取和处理的效率。
使用 redis 队列
Scrapy 爬虫分发还有一种简单粗暴的实现方式,就是在 start_requests() 方法中写一个死循环,在循环中监控一个 Redis 队列,一旦发现有消息就 pop() 出去,然后将请求放入 Scrapy 原生的请求队列中。Scrapy 的其他线程会从队列中取出请求继续执行。这样就巧妙地利用了 Redis 的高性能和 Scrapy 的多线程模型。
Scrapy多线程模型
在Scrapy的设置中可以设置多线程的数量。它的多线程大致是这样的:主线程通过yield不断的往scrapy请求队列中push请求,子线程并发的从请求队列中pop请求,然后把请求交给Downloader去处理。同时会有专门的线程去处理返回的Response。
优点和缺点
使用redis队列的优点是实现简单,不需要修改Scrapy源码。但是它的缺点也很明显,它的请求队列比较冗余,Scrapy需要一直运行。Python常驻内存的申请,会出现内存回收的问题,由于自动回收机制不能很好的回收垃圾,导致进程占用的内存越来越大,直到占满。我亲测Python中手动进行垃圾回收并不能完全解决这个问题。PHP等语言中也存在这个问题。
解决方法有两种:定时重启进程和使用多进程。线程产生的对象不会随着线程结束而被销毁,而进程产生的对象则会随着进程结束而被释放。因此,对产生的对象的所有操作都在新的进程中执行,而新进程的生命周期就是爬虫请求的生命周期。
简单爬虫实现分发
Scrapy 是一个非常强大的爬虫框架,但是很多时候我们写的爬虫都比较简单,所以根本不需要 Scrapy。利用 Python 第三方库requests,我们可以快速写出一个简单的爬虫。但是很多时候我们需要将这些简单的爬虫部署到多台机器上。利用上面的 Redis 方式,也可以实现简单爬虫的分发。
▍2.3 验证码识别
模拟浏览器自动化操作
使用selenium+webdriver或者Selenium+Phantomjs动态加载页面,模拟自动化操作(如登录、输入内容、截图、点击按钮等)。支持的浏览器包括IE(7、8、9)、Mozilla Firefox、Google Chrome等。
识别码
编码平台
网站
云速度
联众游戏答案
超人编码中心
云编码
卷积神经网络
使用n个卷积层+池化层+全连接卷积神经网络进行模型训练
如下图所示,在5×5的图像上做3×3的卷积核卷积,每一次卷积都是一种特征提取的方式,就像一个筛子,过滤掉图像中符合条件的部分(激活值越大,越符合条件)。
pythontensorflow_cnn_train.py
读取数字+小写字母的验证码,定义CNN进行训练,使用softmax进行分类,准确率达到50%时停止训练,保存模型
pythontensorflow_cnn_测试模型.py
测试模型
3. 结论
▍4.参考文献