分享

用 web-harvest 挖掘需要的数据-非决定性因素-搜狐博客

 ShangShujie 2010-05-06

    首先,在官方网站下载web-harvest, 目前最新版本是1.0,下载页面分三个下载包,分别是webharvest1-exe.zipwebharvest1-bin.zipwebharvest1-project.zip,他们没实质区别,第一个是包含了全部第三方包(一起打入了 同一个jar文件直接可运行),第二个做为一个中间件出现,附带了所有独立的第三方jar包,第三个则是源码,当然要最大的灵活性自然选择下载源码了:》

下载下来后再eclipse建立一个空项目,把所有解压出来的文件夹仍进去,然后把src和config设为source folder (源码目录) 然后看到default包下面有个Test.java的文件,下面我们来看看这个文件:

        ScraperConfiguration config = new ScraperConfiguration("c:/temp/scrapertest/dddd.xml");
        Scraper scraper = new Scraper(config, "c:/temp/scrapertest/");
        scraper.setDebug(true);
        long startTime = System.currentTimeMillis();
        scraper.execute();
        System.out.println("time elapsed: " + (System.currentTimeMillis() - startTime));

除去log4j的注解外,剩下的就是这几行代码啦,我们看到运行挖掘任务只需要3行代码,创建config,用config和挖取到数据存储目录做 参数创建Scraper,然后执行就OK。

好了,先试试,它能不能工作,在刚才解压出来的文件中,有一个examples文件夹下面有很多,配置文件可以先试试手,首先,看看图片挖取的例子 google_images.xml,更改上面的两行代码

        ScraperConfiguration config = new ScraperConfiguration("E:/workspace/webharvest/examples/google_images.xml");

        Scraper scraper = new Scraper(config, " E:/workspace/webharvest/examples/");

然后运行这个Test在console窗口会看到抓取过程,完成后再E:\workspace\webharvest\examples \google_images目录下就能看到刚才抓取到的所有图片了,抓取非常简单,到此为止,我们看看他的配置文 件,google_images.xml到底有什么魔法。

在google_images.xml中,这个配置文件中首先引用了一个functions.xml,在google_images.xml同级目 录下,我们先看看这个文件。这个文件中定义了一个function(函数)名字是download-multipage-list虽然不符合java函数 定义规则,但是这里只是一个函数名,函数return了一个循环出来的结果集,empty标记表示其中的执行结果不包含在返回结果集内,那么主要返回的就 是:
                <xpath expression="${itemXPath}">
                    <var name="content"/>
                </xpath>
这段了,这段代码 表示,用xpath方式(解析规则是expression表达式决定的)解析引用的content内容,做为一个行记录(这个行记录会被默认封装成一个 List(不是普通的list而是:org.webharvest.runtime.variables.ListVariable);

循环的主体主要实现读取数页(多少页由$maxloops变量决定)的数据.


现在看看empty内部的功能:

首先
<var-def name="content">
    <html-to-xml>
        <http url="${pageUrl}"/>
    </html-to-xml>
</var-def>
是定义一个content变量,内容是访 问${pageUrl}页面内容。

接着:
<var-def name="nextLinkUrl">
    <xpath expression="${nextXPath}">
        <var name="content"/>
    </xpath>
</var-def>

是用xpath表达式(${nextXPath})取content变量内部的值(也就是刚才${pageUrl}页面解析)得到下一页的URL地 址。

<var-def name="pageUrl">
      <template>${sys.fullUrl(pageUrl.toString(), nextLinkUrl.toString())}</template>
</var-def>

对pageUrl重新赋值,将下一页赋值给pageUrl下次循环读下一页数据解析。

好了这个函数简单的说就是用来分页取数据的。

回到google-images.xml文件我们继续看:

      <!-- defines search keyword and start URL -->
      <var-def name="search" overwrite="false">platon</var-def>
      <var-def name="url">
            <xpath expression="//noscript//a/@href[1]">
                  <html-to-xml>
                   <http url="http://images.google.com/images?q=${search}&hl=en&btnG=Search+Images"/>
                  </html-to-xml>
            </xpath>
    </var-def>

很简单,定义一个变量做搜索条件给url中,然后用html-to-xml标记把http标记访问url的页面html内容转换为xml,最后用 xpath一个表达式得到页面真实的url(看来google确实比较麻烦,其他网站可以直接得到url的)。

      <!-- collects all image URLs -->
      <var-def name="imgLinks">
        <call name="download-multipage-list">
            <call-param name="pageUrl"><var name="url"/></call-param>
            <call-param name="nextXPath">//td[.='Next']/a/@href</call-param>
            <call-param name="itemXPath">//img[contains(@src, 'images?q=tbn')]/@src</call-param>
            <call-param name="maxloops">5</call-param>
        </call>
      </var-def>

    这段的功能就是调用分页函数,把itemXPath参数中的xpath表达式内容,限定解析的页面内容封装成一个list啦

首先定义了4个参数,然后调用functions定义的download-multipage-list函数,最后将返回值赋给 imgLinks(这就完成了图片url的抓取工作了)。

    <!-- download images and saves them to the files -->
    <loop item="link" index="i" filter="unique">
        <list>
            <var name="imgLinks"/>
        </list>
        <body>
            <file action="write" type="binary" path="google_images/${search}_${i}.gif">
                <http url="${sys.fullUrl(url, link)}"/>
            </file>
        </body>
    </loop>

虽然已经完成了抓取过程,但是图片还没有保存在本地呢,这里我们就要循环调用file标签,来把url中的图片逐一保存在本地啦。
这里很简 单,需要注意的就是loop循环,比较不同的是loop必须包含一个list和body,会把list逐一迭代出来,body代码中有句 sys.fullUrl函数,是用来处理抓到的相对地址修正为完整的http开头的绝对地址,参数url是前面我们定义的,link是loop循环体变量 在循环里面定义的。

看完了这个我们做个我们看到只要用xpath表达式,对任何页面的相对位置抓取都不是问题了。

Web-harvest已经解决了大部分问题,我们要做的就是写配置文件了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多