最近在做网络爬虫抓取数据,遇到几个重要问题,记录下来,以免忘记。
目前用的是第三方开源爬虫框架webmagic,所以暂时记录下来的不是爬虫实现和结构上的问题,而主要是在此框架上的逻辑开发问题。
1.要采集的数据在不同的页面上
比如,采集网站http://down.7po.com/上的应用,在应用列表页面有应用的id等信息,而此应用的详细页面没有列表页面的这些字段信息,那么就要从列表页面和详细页面中取出字段然后再合成一个应用的整体数据。对这个问题,比较直接的思路是,可以将先取出的一部分数据存放在自定义实体,存入数据缓存(比如redis内存数据库),取到另一部分数据时从缓存中匹配读取原来已有的一部分,合并。在个别情况下,可能出现数据不完整的情况,要注意对合并后的数据进行完整性校验。
2.页面元素的抽取和数据的筛选过滤
要抽取页面上的标签元素常使用xpath,Jsoup(包含css选择器等),正则表达式进行抽取。对标签内的数据的筛选过滤可用正则表达式,一些对字符串的操作工具(比如google guava的CharMatcher类,Splitter类等)筛选。使用正则会看起来更美观些。期间我遇到情况有:信息藏在利用工具获取的xpath节点的父节点、信息做了简单防抓取截断甚至js等处理……这些情况可以仔细分析网页源码加以针对解决。
3.html返回后通过js动态获取数据,造成爬取不到目标数据(前端渲染页面问题)
对于这个问题,webmagic官方文档中提出了两种思路:(具体可参考webmagic框架中的这个问题的说明和处理http://webmagic.io/docs/zh/posts/chx-cases/js-render-page.html)
- 在抓取阶段,在爬虫中内置一个浏览器内核,执行js渲染页面后,再抓取。这方面对应的工具有
Selenium
、HtmlUnit
或者PhantomJs
。但是这些工具都存在一定的效率问题,同时也不是那么稳定。好处是编写规则同静态页面一样。 - 因为js渲染页面的数据也是从后端拿到,而且基本上都是AJAX获取,所以分析AJAX请求,找到对应数据的请求,也是比较可行的做法。而且相对于页面样式,这种接口变化可能性更小。缺点就是找到这个请求,并进行模拟,是一个相对困难的过程,也需要相对多的分析经验。