模拟ajax实现网络爬虫——HtmlUnit

    最近在用Jsoup抓取某网站数据,可有些页面是ajax请求动态生成的,去群里问了一下,大神说模拟ajax请求即可。去网上搜索了一下,发现了这篇文章,拿过来先用着试试。

   转帖如下:

网上关于网络爬虫实现方式有很多种,但是很多都不支持Ajax,李兄说:模拟才是王道。确实,如果能够模拟一个没有界面的浏览器,还有什么不能做到的呢? 关于解析Ajax网站的框架也有不少,我选择了HtmlUnit,官方网站:http://htmlunit.sourceforge.net /,htmlunit可以说是一个Java版本的无界面浏览器,几乎无所不能,而且很多东西都封装得特别完美。这是这几天来积累下来的心血,记录一下。



package com.lanyotech.www.wordbank;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.List;
import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.ScriptResult;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect; 

public class WorldBankCrawl { 

    private static String TARGET_URL = "http://databank.worldbank.org/ddp/home.do"; 

    public static void main(String[] args) throws FailingHttpStatusCodeException, MalformedURLException, IOException {
        //模拟一个浏览器
        WebClient webClient = new WebClient();
        //设置webClient的相关参数
        webClient.setJavaScriptEnabled(true);
        webClient.setCssEnabled(false);
        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
        webClient.setTimeout(35000);
        webClient.setThrowExceptionOnScriptError(false);
        //模拟浏览器打开一个目标网址
        HtmlPage rootPage= webClient.getPage(TARGET_URL);
        //获取第一个数据库
        HtmlSelect hs = (HtmlSelect) rootPage.getElementById("lstCubes");
        //按要求选择第一个数据库
        hs.getOption(0).setSelected(true);
        //模拟点击Next按钮,跳转到第二个页面
        System.out.println("正在跳转…");
        //执行按钮出发的js事件
        ScriptResult sr = rootPage.executeJavaScript("javascript:setCubeData(2,-1,4,‘/ddp‘);"); 

        //跳转到第二个页面,选择国家
        HtmlPage countrySelect = (HtmlPage) sr.getNewPage();
        //获得包含全部国家信息的选择框页面
        HtmlPage framePage=(HtmlPage)countrySelect.getFrameByName("frmTree1″).getEnclosedPage();
        //获得selectAll按钮,触发js事件
        framePage.executeJavaScript("javascript:TransferListAll(‘countrylst‘,‘countrylstselected‘,‘no‘);SetSelectedCount(‘countrylstselected‘,‘tdcount‘);");
        //获取Next按钮,触发js事件
        ScriptResult electricityScriptResult = framePage.executeJavaScript("javascript:wrapperSetCube(‘/ddp‘)"); 

        System.out.println("正在跳转…");
        //跳转到下一个页面electricitySelect
        HtmlPage electricitySelect = (HtmlPage) electricityScriptResult.getNewPage();
        //获得electricity选择的iframe
        HtmlPage electricityFrame = (HtmlPage) electricitySelect.getFrameByName("frmTree1″).getEnclosedPage();
        //获得选择框
        HtmlSelect seriesSelect = (HtmlSelect) electricityFrame.getElementById("countrylst");
        //获得所有的选择框内容
        List optionList = seriesSelect.getOptions();
        //将指定的选项选中
        optionList.get(1).setSelected(true);
        //模拟点击select按钮                       electricityFrame.executeJavaScript("javascript:TransferList(‘countrylst‘,‘countrylstselected‘,‘no‘);SetSelectedCount(‘countrylstselected‘,‘tdcount‘);");
        //获取选中后,下面的选择框
        HtmlSelect electricitySelected = (HtmlSelect) electricityFrame.getElementById("countrylstselected");
        List list = electricitySelected.getOptions();
        //模拟点击Next按钮,跳转到选择时间的页面
        ScriptResult timeScriptResult = electricityFrame.executeJavaScript("javascript:wrapperSetCube(‘/ddp‘)"); 

        System.out.println("正在跳转…");
        HtmlPage timeSelectPage = (HtmlPage) timeScriptResult.getNewPage();
        //获取选中时间的选择框
        timeSelectPage = (HtmlPage) timeSelectPage.getFrameByName("frmTree1″).getEnclosedPage();
        //选中所有的时间                timeSelectPage.executeJavaScript("javascript:TransferListAll(‘countrylst‘,‘countrylstselected‘,‘no‘);SetSelectedCount(‘countrylstselected‘,‘tdcount‘);");
        //点击Next按钮
        ScriptResult exportResult = timeSelectPage.executeJavaScript("javascript:wrapperSetCube(‘/ddp‘)"); 

        System.out.println("正在跳转…");
        //转到export页面
        HtmlPage exportPage = (HtmlPage) exportResult.getNewPage();
        //点击页面上的Export按钮,进入下载页面
        ScriptResult downResult = exportPage.executeJavaScript("javascript:exportData(‘/ddp‘ ,‘EXT_BULK‘ ,‘WDI_Time=51||WDI_Series=1||WDI_Ctry=244||‘ );"); 

        System.out.println("正在跳转…");
        HtmlPage downLoadPage = (HtmlPage) downResult.getNewPage();
        //点击Excel图标,开始下载
        ScriptResult downLoadResult = downLoadPage.executeJavaScript("javascript:exportData(‘/ddp‘,‘BULKEXCEL‘);");
        //下载Excel文件
        InputStream is = downLoadResult.getNewPage().getWebResponse().getContentAsStream(); 

        OutputStream fos = new FileOutputStream("d://test.xls");
        byte[] buffer=new byte[1024*30];
        int len=-1;
        while((len=is.read(buffer))>0){
            fos.write(buffer, 0, len);
        }
        fos.close();
        fos.close();
        System.out.println("Success!");
    }
}

 

注释:

  /**HtmlUnit请求web页面*/
        WebClient wc = new WebClient();
        wc.getOptions().setJavaScriptEnabled(true); //启用JS解释器,默认为true
        wc.getOptions().setCssEnabled(false); //禁用css支持
        wc.getOptions().setThrowExceptionOnScriptError(false); //js运行错误时,是否抛出异常
        wc.getOptions().setTimeout(10000); //设置连接超时时间 ,这里是10S。如果为0,则无限期等待
        HtmlPage page = wc.getPage("http://cq.qq.com/baoliao/detail.htm?294064");
        String pageXml = page.asXml(); //以xml的形式获取响应文本 
时间: 2024-08-27 07:30:40

模拟ajax实现网络爬虫——HtmlUnit的相关文章

网络爬虫模拟登陆获取数据并解析实战(二)

目录 分析要获取的数据 程序的结构 构建封装数据的model 模拟登陆程序并解析数据 结果展示 分析要获取的数据 下面继续实战,写一个模拟登陆获取汽车之家,用户信息的程序.如果大家对模拟登陆获取数据不太了解,建议看完http://blog.csdn.net/qy20115549/article/details/52249232,我写的这篇含有抓包获取人人网数据的案例程序,研究透之后,再来看这个要轻松很多. 首先,大家打开汽车之家这个网站(http://i.autohome.com.cn/7741

java如果模拟请求重启路由器(网络爬虫常用),还有java如何下载图片

我们如果在公司或家里使用网络爬虫去抓取自己索要的一些数据的时候,常常对方的网站有defence机制,会给你的http请求返回500错误,只要是相同IP就请求不到数据,这时候我们只能去重启路由器,这样IP地址会改变,网络爬虫就能正常工作了 下面是通过发送Socket请求来模拟路由器的重启指令: protected void rebotadsl() { try { BufferedOutputStream sender = null; String url = baseURL; URL target

关于Java网络爬虫---模拟txt文件上传操作。

业务需求是这样的,公司400业务中客户使用的,400电话号码,可以添加多个目的码你可以理解为转接号码: 这些配置的目的码我们会在网关服务器上配置成白名单,既拥有某些权限.先提出的要求是先添加或者变动目的码要及时同步到网关. 场景: 1.我们的网关服务器接受的白名单(目的码)是已txt文件上传的,数据按照制定的格式保存在txt里面. 2.利用Java网络爬虫模拟txt文件上传.------2018-4-7现在不写了,代码在公司电脑上明天总结一下在写. 原文地址:https://www.cnblog

网络爬虫采集数据几个问题

最近在做网络爬虫抓取数据,遇到几个重要问题,记录下来,以免忘记. 目前用的是第三方开源爬虫框架webmagic,所以暂时记录下来的不是爬虫实现和结构上的问题,而主要是在此框架上的逻辑开发问题. 1.要采集的数据在不同的页面上         比如,采集网站http://down.7po.com/上的应用,在应用列表页面有应用的id等信息,而此应用的详细页面没有列表页面的这些字段信息,那么就要从列表页面和详细页面中取出字段然后再合成一个应用的整体数据.对这个问题,比较直接的思路是,可以将先取出的一

开发网络爬虫应该怎样选择爬虫框架?

有些人问,开发网络爬虫应该选择Nutch.Crawler4j.WebMagic.scrapy.WebCollector还是其他的?这里按照我的经验随便扯淡一下: 上面说的爬虫,基本可以分3类: 1.分布式爬虫:Nutch 2.JAVA单机爬虫:Crawler4j.WebMagic.WebCollector 3. 非JAVA单机爬虫:scrapy 第一类:分布式爬虫         爬虫使用分布式,主要是解决两个问题: 1)海量URL管理 2)网速 现在比较流行的分布式爬虫,是Apache的Nut

网络爬虫技术

1.爬虫技术概述 网络爬虫(Web crawler),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本,它们被广泛用于互联网搜索引擎或其他类似网站,可以自动采集所有其能够访问到的页面内容,以获取或更新这些网站的内容和检索方式.从功能上来讲,爬虫一般分为数据采集,处理,储存三个部分.传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件.聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过

Java开发、网络爬虫、自然语言处理、数据挖掘简介

一.java开发 (1) 应用开发,即Java SE开发,不属于java的优势所在,所以市场占有率很低,前途也不被看好. (2) web开发,即Java Web开发,主要是基于自有或第三方成熟框架的系统开发,如ssh.springMvc.springside.nutz.,面向各自不同的领域,像OA.金融.教育等有非常成熟案例,这是目前最大的市场所在,故人称“java为web而生”.但目前看它的缺点入门不高,所以待遇相对中等,上升空间很有限且缓慢. (3)移动开发(Android),是目前的大趋势

开发网络爬虫应该如何选择爬虫框架?

有些人问,开发网络爬虫应该选择Nutch.Crawler4j.WebMagic.scrapy.WebCollector还是其它的?这里依照我的经验随便扯淡一下: 上面说的爬虫,基本能够分3类: 1.分布式爬虫:Nutch 2.JAVA单机爬虫:Crawler4j.WebMagic.WebCollector 3. 非JAVA单机爬虫:scrapy 第一类:分布式爬虫         爬虫使用分布式.主要是解决两个问题: 1)海量URL管理 2)网速 如今比較流行的分布式爬虫,是Apache的Nut

学 Java 网络爬虫,需要哪些基础知识?

说起网络爬虫,大家想起的估计都是 Python ,诚然爬虫已经是 Python 的代名词之一,相比 Java 来说就要逊色不少.有不少人都不知道 Java 可以做网络爬虫,其实 Java 也能做网络爬虫而且还能做的非常好,在开源社区中有不少优秀的 Java 网络爬虫框架,例如 webmagic .我的第一份正式工作就是使用 webmagic 编写数据采集程序,当时参与了一个舆情分析系统的开发,这里面涉及到了大量网站的新闻采集,我们就使用了 webmagic 进行采集程序的编写,由于当时不知道其设