文档章节

SeimiCrawler+SeimiAgent完美解决动态页面渲染Ajax抓取问题

无极小子
 无极小子
发布于 2016/04/16 02:00
字数 1231
阅读 636
收藏 6

钉钉、微博极速扩容黑科技,点击观看阿里云弹性计算年度发布会!>>>

前言

曾几何时,动态页面(ajax,内部js二次渲染等等)信息提取一直都是爬虫开发者的心痛点,一句话,实在没有合适的工具。尤其在Java里面,像htmlunit这种工具都算得上解析动态页面的神器了,但是他依然不够完备,达不到浏览器级的解析效果,遇到稍微复杂点的页面就不行了。在经历的各种痛与恨后,笔者决定干脆开发一款专为应对抓取,监控,以及测试这类场景使用的动态页面渲染处理服务器。要达到浏览器级的效果,那必须基于浏览器内核来开发,幸运的是我们有开源的webkit,更为幸运的是我们有对开发者更为友好的QtWebkit。所以SeimiAgent就这样诞生了。

SeimiAgent简介

SeimiAgent是基于QtWebkit开发的可在服务器端后台运行的一个webkit服务,可以通过SeimiAgent提供的http接口向SeimiAgent发送一个load请求(需求加载的URL以及对这个页面接受的渲染时间或是使用什么代理等参数),通过SeimiAgent去加载并渲染想要处理的动态页面,然后将渲染好的页面直接返给调用方进行后续处理,所以运行的SeimiAgent服务是与语言无关的,任何一种语言或框架都可以通过SeimiAgent提供的标准http接口来获取服务。SeimiAgent的加载渲染环境都是通用浏览器级的,所以不用担心他对动态页面的处理能力。目前SeimiAgent只支持返回渲染好的HTML文档,后续会增加图像快照已经PDF的支持,方便更为多样化的使用需求。

使用演示

demo

SeimiCrawler简介

SeimiCrawler是一个敏捷的,独立部署的,支持分布式的Java爬虫框架,希望能在最大程度上降低新手开发一个可用性高且性能不差的爬虫系统的门槛,以及提升开发爬虫系统的开发效率。在SeimiCrawler的世界里,绝大多数人只需关心去写抓取的业务逻辑就够了,其余的Seimi帮你搞定。设计思想上SeimiCrawler受Python的爬虫框架Scrapy启发很大,同时融合了Java语言本身特点与Spring的特性,并希望在国内更方便且普遍的使用更有效率的XPath解析HTML,所以SeimiCrawler默认的HTML解析器是JsoupXpath(独立扩展项目,非jsoup自带),默认解析提取HTML数据工作均使用XPath来完成(当然,数据处理亦可以自行选择其他解析器)。

整合使用

部署SeimiAgent

下载解压缩就不表了,上面的动态图中也有演示,下载地址可以到SeimiAgent主页找到。进到SeimiAgent的bin目录,执行:

./SeimiAgent -p 8000

这是启动SeimiAgent服务并监听8000端口。接下来实际上就可以使用任何语言通过http请求发送加载页面的请求,然后得到渲染后的结果。当然我们这里是要介绍SeimiCrawler是如何整合使用SeimiAgent的。

SeimiCrawler配置

SeimiCrawler在v0.3.0版本中已经内置支持了SeimiAgent,只需要开发者配置好SeimiAgent的地址和端口,然后在生成具体Request时选择是否要提交给SeimiAgent,并且指定如何递交。直接上个完整例子在注释中说明吧:

package cn.wanghaomiao.crawlers;

import cn.wanghaomiao.seimi.annotation.Crawler;
import cn.wanghaomiao.seimi.def.BaseSeimiCrawler;
import cn.wanghaomiao.seimi.struct.Request;
import cn.wanghaomiao.seimi.struct.Response;
import cn.wanghaomiao.xpath.model.JXDocument;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;

/**
 * 这个例子演示如何使用SeimiAgent进行复杂动态页面信息抓取
 * @author 汪浩淼 et.tw@163.com
 * @since 2016/4/14.
 */
@Crawler(name = "seimiagent")
public class SeimiAgentDemo extends BaseSeimiCrawler{

    /**
     * 在resource/config/seimi.properties中配置方便更换,当然也可以自行根据情况使用自己的统一配置中心等服务。这里配置SeimiAgent服务所在地址。
     */
    @Value("${seimiAgentHost}")
    private String seimiAgentHost;

    //SeimiAgent监听的端口好,如上文中的8000
    @Value("${seimiAgentPort}")
    private int seimiAgentPort;

    @Override
    public String[] startUrls() {
        return new String[]{"https://www.baidu.com"};
    }

    @Override
    public String seimiAgentHost() {
        return this.seimiAgentHost;
    }

    @Override
    public int seimiAgentPort() {
        return this.seimiAgentPort;
    }

    @Override
    public void start(Response response) {
        Request seimiAgentReq = Request.build("https://www.souyidai.com","getTotalTransactions")
                .useSeimiAgent()
              // 告诉SeimiAgent针对这个请求是否使用cookie,如果没有设置使用当前Crawler关于cookie使用条件作为默认值。
              //.setSeimiAgentUseCookie(true)
              // 设置全部load完成后给SeimiAgent多少时间用于执行js并渲染页面,单位为毫秒
                .setSeimiAgentRenderTime(5000);
        push(seimiAgentReq);
    }

    /**
     * 获取搜易贷首页总成交额
     * @param response
     */
    public void getTotalTransactions(Response response){
        JXDocument doc = response.document();
        try {
            String trans = StringUtils.join(doc.sel("//div[@class='homepage-amount']/div[@class='number font-arial']/div/span/text()"),"");
            logger.info("Final Res:{}",trans);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

配置文件seimi.properties

seimiAgentHost=127.0.0.1
seimiAgentPort=8000

启动

public class Boot {
    public static void main(String[] args){
        Seimi s = new Seimi();
        s.start("seimiagent");
    }
}

SeimiCrawler启动后就可以看到你想要的搜易贷交易总额了。

无极小子

无极小子

粉丝 15
博文 8
码字总数 6214
作品 4
朝阳
程序员
私信 提问
加载中
请先登录后再评论。
WebMagic抓取前端Ajax渲染的页面

抓取前端渲染的页面 随着AJAX技术不断的普及,以及现在AngularJS这种Single-page application框架的出现,现在js渲染出的页面越来越多。对于爬虫来说,这种页面是比较讨厌的:仅仅提取HTML内...

liuyuantao
2016/04/09
68
0
WebMagic学习-抓取前端渲染的页面

写在前面: 参考:官方文档http://webmagic.io/docs/zh/posts/chx-cases/js-render-page.html 两种做法: 在抓取阶段,在爬虫中内置一个浏览器内核,执行js渲染页面后,再抓取。这方面对应的...

安小乐
2016/10/10
244
0
支持ajax的静态页面生成

目前主流的页面静态技术都是基于模板生成的,但是对于一些采用ajax+js渲染的页面,这种方法是无能为力的。要解决这个问题,首先要有一个能模拟浏览器的运行环境,其他问题都比较容易解决。能...

温佐镜
2013/12/08
2.7K
0
SeimiCrawler v0.3.0 发布,Java 爬虫框架

SeimiCrawler v0.3.0 发布了,详细的改进记录如下: Change log v0.3.0 内置支持SeimiAgent,完美解决动态页面渲染抓取问题 修复自动跳转在某些情况存在的bug...

无极小子
2016/04/16
865
0
探究SEO与VUE首屏渲染及其解决方案

前言 【音乐博客】上线啦! 开开心心部署到服务器,然后满怀欣喜打开首页,结果发现有点小慢,这就很不愉快啦 下面来解决vue首屏渲染 五个方面 1. SPA单页面应用 首屏打开速度很慢,因为用户...

osc_a5w6ccj0
05/31
7
0

没有更多内容

加载失败,请刷新页面

加载更多

在JavaScript中从字符串中删除所有非数字字符 - Strip all non-numeric characters from string in JavaScript

问题: Consider a non-DOM scenario where you'd want to remove all non-numeric characters from a string using JavaScript/ECMAScript. 考虑一个非DOM场景,您希望使用JavaScript / EC......

法国红酒甜
27分钟前
14
0
Quartz的Misfire处理规则 错过任务执行时间的处理机制

调度(scheduleJob)或恢复调度(resumeTrigger,resumeJob)后不同的misfire对应的处理规则 CronTrigger withMisfireHandlingInstructionDoNothing ——不触发立即执行 ——等待下次Cron触发频率...

独钓渔
今天
4
0
如何在Django视图中合并两个或多个查询集? - How to combine two or more querysets in a Django view?

问题: I am trying to build the search for a Django site I am building, and in that search, I am searching in 3 different models. 我正在尝试搜索要构建的Django网站,在该搜索中,我......

javail
今天
5
0
PHP解析/语法错误; 以及如何解决它们? - PHP parse/syntax errors; and how to solve them?

问题: Everyone runs into syntax errors. 每个人都遇到语法错误。 Even experienced programmers make typos. 即使是经验丰富的程序员也会打错字。 For newcomers, it's just part of the......

fyin1314
今天
20
0
OSChina 周三乱弹 —— 公主是大王的,命是自己的。小怪也要养家糊口啊!

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @巴拉迪维 :郭燕的单曲《下半生》 最近听一些轻快的歌 #今日歌曲推荐# 《下半生》 - 郭燕 手机党少年们想听歌,请使劲儿戳(这里) @锦年 :...

小小编辑
今天
38
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部