【高额扑克第九季】High Stakes Poker中文|播客吧直播
14
2024 / 10 / 03
本例中用到的maven坐标变化如下:
在百度中搜索笑话,看到这么一个网站:http://www.jokeji.cn/,点进去看看,里面的内容比较简单,也比较有趣,呵呵,就它了,我们今天的示例就是如何利用TinySpider来进行网页抓取。
示例1:获取某个分类下的笑话列表
首先在笑话分类中看到个爆笑男女,呵呵,先拿它小试一下,看看是否有效果。
首先编写一个main方法,内容如下:
下面简单用通俗的话介绍一下,上面代码的作用:
首先构建一个爬虫,字符集是GBK,然后建立一个Watcher,Watcher用于在抓取的内容中,进行数据过滤。
如果过滤到内容呢,就执行PrintJokejiProcessor处理器进行处理。
后面设置过滤方式,是查找div标签,并且其class属性是list_title,最后,让爬虫去爬取http://www.jokeji.cn/list29_1.htm页面。
OK主程序就写完了,上面有个类PrintJokejiProcessor也是需要自己写的,内容如下:
这个类的意思是,node就是上面说的包含list_title属性的div,然后从其里面找到所有属性名是a的节点,并打印其内容。
运行之,运行结果如下:
从上面的的列表看,确实已经正确抓取的到数据,小试成功。
示例2:抓取所有的分类列表
先先Main方法
再写里面的处理器:
下面是运行结果:
呵呵,目录就打印出来了,当然后面附加了每个分类下的笑话数,要去掉它,太简单了因此,这里就不再耗费时间了。
示例3:打印所有分类下的笑话标题:
这里就简单的处理一下,把上面的两个类小改一下:
JokejiTest类的main方法修改成静态方法processUrl ,然后把下面的处理的URL变成参数传入
PrintJokejiCategoryProcessor类改成下面的样子
就是说打出标题之后,再去利用URL进行下一层的数据抓取。
下面是调整之后的运行结果:
呵呵,还没有呢,因为你会发现有的分类下是有分页的,现在只是打出了第一页的内容。
示例4:处理分页
接下来呢,为了避免有人去直接抓取人家的网页,我会贴局部代码,但是不会贴完整的代码了。当然,你能根据局部代码,整出完整的,那说明你聪明过人,偶也没有办法了。
其实,一个页面里,可以添加多个Watcher。
比如说,在笑话列表页面,再增加一下Watcher类似下面这样:
就可以把后续页面都抓住了,抓住之后怎么处理呢?有这么个类NextPageProcessor:
就是把翻到的页找出来,执行同样的处理,就可以了。运行一下,乖乖,所有的分类及分类下的标题都打印出来了。
示例5:具体的笑话的抓取
具体的笑话抓取,代码片断不能贴了,只说原理。
访问一个页面,很简单的就可以找到内容的节点,并抓取内容出来。
在列表的位置里不是有个打印笑话标题的处理么,只要把href中的连接读出来,传递到具体的笑话抓取的部分,就可以完成整个笑话网站的内容抓取。至于抓取到数据之后你是打印一下就好还是存放数据库还是....想干啥干啥,那就是看你自己的了。
示例6:给TinySpider增加多线程处理
值得注意的是,如果要处理的网站有防爬虫机制,这样子很快会触发对方反应的。这里假设没有,仅讨论如何增加多线程处理模式。
没有增加多线程处理的模式,是上面的这个样子。如何把它处理成多线程模式呢?SoEasy,首先增加一个对线程组的工程依赖。
接下来,把上面的类重构成下面的样子。
运行一看,下载页面确实已经变成多线程的了。
示例7:TinySpider与分布式集成
Tiny框架有个特点,就是干啥的就是干啥的,比如示例6当中,解决多线程的,有个专门的线程组工程来解决,网络爬虫只专注于网络爬虫机制相关的内容。那么要做分布式,也是一样子,Tiny有个专门的分布式工程。引入就可以加入分布式机制。
要把单机的TinySpider变成分布式的,首先要解决的一个问题就是UrlRepository的问题,UrlRepository是避免URL被重复处理的机制,保存有所有已经处理过的URL列表。那可以用各种方式来写这个URL仓库,可以用数据库,可以用缓冲,或者其它复杂的手段来现。
接下来就如何进行分布式抓取了:
先来开发个工人:
工人从输入仓库里拿出url列表,然后循环处理之。
然后要实现一个任务分解器:
上面的任务就根据工人数据对要处理的url进行分解,分解成多个仓库。
接下来就是构建主任务中心了:
当然也可以在很多台计算机上都增加工人进来:
注意,上面的代码不同之处,在于一个是 JobCenterLocal和JobCenterRemote,Local相当于服务器,Remote相当于客户端,因此,只能有一个Local,可以有多个Remote。
上面把分布式的工作做好准备了,接下来进行分布式调用:
还是修改PrintJokejiProcessor
如此,就可以通过N台机器来共同完成页面抓取了。
相对前面的例子,确实用分布式,内容要多一些,但是应该还好了,代码行不多,只是概念多了一点,因此要去学习分布式计算相关的知识了:
http://my.oschina.net/tinyframework/blog/196486
http://my.oschina.net/tinyframework/blog/196373
结尾
上面的类名,方法名,变量名都是随便取的,重构之。一个完整的网站内容抓取就算完工了。最后统计了一下源代码,不到200行。import语句比真正干活的代码还多,真正干活的在方法中的语句也就100行左右。
发表评论
暂时没有评论,来抢沙发吧~