`
hao861002
  • 浏览: 86420 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

htmlParser收集记录

阅读更多

   

     需要做一个垂直搜索引擎,比较了nekohtml和htmlparser 的功能,尽管nekohtml在容错性、性能等方面的口碑好像比htmlparser好(htmlunit也用的是nekohtml),但感觉 nekohtml的测试用例和文档都比htmlparser都少,而且htmlparser基本上能够满足垂直搜索引擎页面处理分析的需求,因此先研究一下htmlparser的使用,有空再研究nekohtml和mozilla html parser的使用。

    html的功能还是官方说得最为清楚,

引用
    HTML Parser is a Java library used to parse HTML in either a linear or nested fashion. Primarily used for transformation or extraction, it features filters, visitors, custom tags and easy to use JavaBeans. It is a fast, robust and well tested package.

    The two fundamental use-cases that are handled by the parser are extraction and transformation (the syntheses use-case, where HTML pages are created from scratch, is better handled by other tools closer to the source of data). While prior versions concentrated on data extraction from web pages, Version 1.4 of the HTMLParser has substantial improvements in the area of transforming web pages, with simplified tag creation and editing, and verbatim toHtml() method output.



    研究的重点还是extraction的使用,有空再研究transformation的使用。


1、htmlparser对html页面处理的数据结构

 

 





如图所示,HtmlParser采用了经典的Composite模式,通过RemarkNode、TextNode、TagNode、AbstractNode和Tag来描述HTML页面各元素。

    * org.htmlparser.Node:

    Node接口定义了进行树形结构节点操作的各种典型操作方法,包括:

    节点到html文本、text文本的方法:toPlainTextString、toHtml

   典型树形结构遍历的方法:getParent、getChildren、getFirstChild、getLastChild、getPreviousSibling、getNextSibling、getText

    获取节点对应的树形结构结构的顶级节点Page对象方法:getPage

    获取节点起始位置的方法:getStartPosition、getEndPosition

   Visitor方法遍历节点时候方法:accept (NodeVisitor visitor)

    Filter方法:collectInto (NodeList list, NodeFilter filter)

    Object方法:toString、clone

    * org.htmlparser.nodes.AbstractNode:

    AbstractNode是形成HTML树形结构抽象基类,实现了Node接口。

    在htmlparser中,Node分成三类:

    RemarkNode:代表Html中的注释

    TagNode:标签节点。

    TextNode:文本节点

    这三类节点都继承AbstractNode。

    * org.htmlparser.nodes.TagNode:

    TagNode包含了对HTML处理的核心的各个类,是所有TAG的基类,其中有分为包含其他TAG的复合节点ComositeTag和不包含其他TAG的叶子节点Tag。

    复合节点CompositeTag:  

        AppletTag,BodyTag,Bullet,BulletList,DefinitionList,DefinitionListBullet,Div,FormTag,FrameSetTag,HeadingTag,

        HeadTag,Html,LabelTag,LinkTag,ObjectTag,ParagraphTag,ScriptTag,SelectTag,Span,StyleTag,TableColumn,

       TableHeader,TableRow,TableTag,TextareaTag,TitleTag

    叶子节点TAG:

        BaseHrefTag,DoctypeTag,FrameTag,ImageTag,InputTag,JspTag,MetaTag,ProcessingInstructionTag,
2、htmlparser对html页面处理的算法

主要是如下几种方式

引用

    HTML Parser is a Java library used to parse HTML in either a linear or nested fashion. Primarily used for transformation or extraction, it features filters, visitors, custom tags and easy to use JavaBeans. It is a fast, robust and well tested package.

    The two fundamental use-cases that are handled by the parser are extraction and transformation (the syntheses use-case, where HTML pages are created from scratch, is better handled by other tools closer to the source of data). While prior versions concentrated on data extraction from web pages, Version 1.4 of the HTMLParser has substantial improvements in the area of transforming web pages, with simplified tag creation and editing, and verbatim toHtml() method output.



    研究的重点还是extraction的使用,有空再研究transformation的使用。
1、htmlparser对html页面处理的数据结构

Java代码 复制代码
  1.     * 采用Visitor方式访问Html   
  2.   
  3. try {   

  1.     Parser parser = new Parser();   
  2.     parser.setURL(”http://www.google.com”);   
  3.     parser.setEncoding(parser.getEncoding());   
  4.     NodeVisitor visitor = new NodeVisitor() {   
  5.         public void visitTag(Tag tag) {   
  6.             logger.fatal(”testVisitorAll()  Tag name is :”   
  7.                     + tag.getTagName() + ” \n Class is :”   
  8.                     + tag.getClass());   
  9.         }   
  10.   
  11.     };   
  12.   
  13.     parser.visitAllNodesWith(visitor);   
  14. catch (ParserException e) {   
  15.     e.printStackTrace();   
  16. }   
  17.   
  18.     * 采用Filter方式访问html   
  19.   
  20. try {   
  21.   
  22.     NodeFilter filter = new NodeClassFilter(LinkTag.class);   
  23.     Parser parser = new Parser();   
  24.     parser.setURL(”http://www.google.com”);   
  25.     parser.setEncoding(parser.getEncoding());   
  26.     NodeList list = parser.extractAllNodesThatMatch(filter);   
  27.     for (int i = 0; i < list.size(); i++) {   
  28.         LinkTag node = (LinkTag) list.elementAt(i);   
  29.         logger.fatal(”testLinkTag() Link is :” + node.extractLink());   
  30.     }   
  31. catch (Exception e) {   
  32.     e.printStackTrace();   
  33. }   
  34.   
  35.     * 采用org.htmlparser.beans方式   
  36.   
  37. 另外htmlparser 还在org.htmlparser.beans中对一些常用的方法进行了封装,以简化操作,例如:   
  38.   
  39. Parser parser = new Parser();   
  40.   
  41. LinkBean linkBean = new LinkBean();   
  42. linkBean.setURL(”http://www.google.com”);   
  43. URL[] urls = linkBean.getLinks();   
  44.   
  45. for (int i = 0; i < urls.length; i++) {   
  46.     URL url = urls[i];   
  47.     logger.fatal(”testLinkBean() -url  is :” + url);   
  48. }   
  49.   
  50.     
  51. 3、htmlparser关键包结构说明   
  52.   
  53.     htmlparser其实核心代码并不多,好好研究一下其代码,弥补文档不足的问题。同时htmlparser的代码注释和单元测试用例还是很齐全的,也有助于了解htmlparser的用法。   
  54.   
  55.   
  56. 3.1、org.htmlparser   
  57.   
  58.     定义了htmlparser的一些基础类。其中最为重要的是Parser类。   
  59.   
  60.     Parser是htmlparser的最核心的类,其构造函数提供了如下:Parser.createParser (String html, String charset)、 Parser ()、Parser (Lexer lexer, ParserFeedback fb)、Parser (URLConnection connection, ParserFeedback fb)、Parser (String resource, ParserFeedback feedback)、 Parser (String resource)   
  61.   
  62.   各构造函数的具体用法及含义可以查看其代码,很容易理解。   
  63.   
  64.   Parser常用的几个方法:   
  65.   
  66.     *   elements获取元素   
  67.   
  68.     Parser parser = new Parser (”http://www.google.com”);   
  69.     for (NodeIterator i = parser.elements (); i.hasMoreElements (); )   
  70.       processMyNodes (i.nextNode ());   
  71.   
  72.     * parse (NodeFilter filter):通过NodeFilter方式获取   
  73.     * visitAllNodesWith (NodeVisitor visitor):通过Nodevisitor方式   
  74.     * extractAllNodesThatMatch (NodeFilter filter):通过NodeFilter方式   
  75.   
  76. 3.2、org.htmlparser.beans   
  77.   
  78.     对Visitor和Filter的方法进行了封装,定义了针对一些常用html元素操作的bean,简化对常用元素的提取操作。   
  79.   
  80.     包括:FilterBean、HTMLLinkBean、HTMLTextBean、LinkBean、StringBean、BeanyBaby等。   
  81. 3.3、org.htmlparser.nodes   
  82.   
  83.     定义了基础的node,包括:AbstractNode、RemarkNode、TagNode、TextNode等。   
  84. 3.4、org.htmlparser.tags   
  85.   
  86.     定义了htmlparser的各种tag。   
  87. 3.5、org.htmlparser.filters   
  88.   
  89.     定义了htmlparser所提供的各种filter,主要通过extractAllNodesThatMatch (NodeFilter filter)来对html页面指定类型的元素进行过滤,包括:AndFilter、CssSelectorNodeFilter、 HasAttributeFilter、HasChildFilter、HasParentFilter、HasSiblingFilter、 IsEqualFilter、LinkRegexFilter、LinkStringFilter、NodeClassFilter、 NotFilter、OrFilter、RegexFilter、StringFilter、TagNameFilter、XorFilter   
  90. 3.6、org.htmlparser.visitors   
  91.   
  92.    定义了htmlparser所提供的各种visitor,主要通过visitAllNodesWith (NodeVisitor visitor)来对html页面元素进行遍历,包括:HtmlPage、LinkFindingVisitor、NodeVisitor、 ObjectFindingVisitor、StringFindingVisitor、TagFindingVisitor、 TextExtractingVisitor、UrlModifyingVisitor   
  93.   
  94.     
  95. 3.7、org.htmlparser.parserapplications   
  96.   
  97.    定义了一些实用的工具,包括LinkExtractor、SiteCapturer、StringExtractor、WikiCapturer,这几个类也可以作为htmlparser使用样例。   
  98. 3.8、org.htmlparser.tests   
  99.   
  100.    对各种功能的单元测试用例,也可以作为htmlparser使用的样例。   
  101.   
  102.     
  103. 4、htmlparser的使用样例   
  104.   
  105.     
  106.   
  107. import java.net.URL;   
  108.   
  109. import junit.framework.TestCase;   
  110.   
  111. import org.apache.log4j.Logger;   
  112. import org.htmlparser.Node;   
  113. import org.htmlparser.NodeFilter;   
  114. import org.htmlparser.Parser;   
  115. import org.htmlparser.Tag;   
  116. import org.htmlparser.beans.LinkBean;   
  117. import org.htmlparser.filters.NodeClassFilter;   
  118. import org.htmlparser.filters.OrFilter;   
  119. import org.htmlparser.filters.TagNameFilter;   
  120. import org.htmlparser.tags.HeadTag;   
  121. import org.htmlparser.tags.ImageTag;   
  122. import org.htmlparser.tags.InputTag;   
  123. import org.htmlparser.tags.LinkTag;   
  124. import org.htmlparser.tags.OptionTag;   
  125. import org.htmlparser.tags.SelectTag;   
  126. import org.htmlparser.tags.TableColumn;   
  127. import org.htmlparser.tags.TableRow;   
  128. import org.htmlparser.tags.TableTag;   
  129. import org.htmlparser.tags.TitleTag;   
  130. import org.htmlparser.util.NodeIterator;   
  131. import org.htmlparser.util.NodeList;   
  132. import org.htmlparser.util.ParserException;   
  133. import org.htmlparser.visitors.HtmlPage;   
  134. import org.htmlparser.visitors.NodeVisitor;   
  135. import org.htmlparser.visitors.ObjectFindingVisitor;   
  136.   
  137. public class ParserTestCase extends TestCase {   
  138.   
  139.     private static final Logger logger = Logger.getLogger(ParserTestCase.class);   
  140.   
  141.     public ParserTestCase(String name) {   
  142.         super(name);   
  143.     }   
  144.     /*  
  145.      * 测试ObjectFindVisitor的用法  
  146.      */  
  147.     public void testImageVisitor() {   
  148.         try {   
  149.             ImageTag imgLink;   
  150.             ObjectFindingVisitor visitor = new ObjectFindingVisitor(   
  151.                     ImageTag.class);   
  152.             Parser parser = new Parser();   
  153.             parser.setURL(”http://www.google.com”);   
  154.             parser.setEncoding(parser.getEncoding());   
  155.             parser.visitAllNodesWith(visitor);   
  156.             Node[] nodes = visitor.getTags();   
  157.             for (int i = 0; i < nodes.length; i++) {   
  158.                 imgLink = (ImageTag) nodes[i];   
  159.                 logger.fatal(”testImageVisitor() ImageURL = “   
  160.                         + imgLink.getImageURL());   
  161.                 logger.fatal(”testImageVisitor() ImageLocation = “   
  162.                         + imgLink.extractImageLocn());   
  163.                 logger.fatal(”testImageVisitor() SRC = “   
  164.                         + imgLink.getAttribute(”SRC”));   
  165.             }   
  166.         }   
  167.         catch (Exception e) {   
  168.             e.printStackTrace();   
  169.         }   
  170.     }   
  171.     /*  
  172.      * 测试TagNameFilter用法  
  173.      */  
  174.     public void testNodeFilter() {   
  175.         try {   
  176.             NodeFilter filter = new TagNameFilter(”IMG”);   
  177.             Parser parser = new Parser();   
  178.             parser.setURL(”http://www.google.com”);   
  179.             parser.setEncoding(parser.getEncoding());   
  180.             NodeList list = parser.extractAllNodesThatMatch(filter);   
  181.             for (int i = 0; i < list.size(); i++) {   
  182.                 logger.fatal(”testNodeFilter() ” + list.elementAt(i).toHtml());   
  183.             }   
  184.         } catch (Exception e) {   
  185.             e.printStackTrace();   
  186.         }   
  187.   
  188.     }   
  189.     /*  
  190.      * 测试NodeClassFilter用法  
  191.      */  
  192.     public void testLinkTag() {   
  193.         try {   
  194.   
  195.             NodeFilter filter = new NodeClassFilter(LinkTag.class);   
  196.             Parser parser = new Parser();   
  197.             parser.setURL(”http://www.google.com”);   
  198.             parser.setEncoding(parser.getEncoding());   
  199.             NodeList list = parser.extractAllNodesThatMatch(filter);   
  200.             for (int i = 0; i < list.size(); i++) {   
  201.                 LinkTag node = (LinkTag) list.elementAt(i);   
  202.                 logger.fatal(”testLinkTag() Link is :” + node.extractLink());   
  203.             }   
  204.         } catch (Exception e) {   
  205.             e.printStackTrace();   
  206.         }   
  207.   
  208.     }   
  209.     /*  
  210.      * 测试<link href=” text=’text/css’ rel=’stylesheet’ />用法  
  211.      */  
  212.     public void testLinkCSS() {   
  213.         try {   
  214.   
  215.             Parser parser = new Parser();   
  216.             parser   
  217.                     .setInputHTML(”<head><title>Link Test</title>”   
  218.                             + “<link href=’/test01/css.css’ text=’text/css’ rel=’stylesheet’ />”   
  219.                             + “<link href=’/test02/css.css’ text=’text/css’ rel=’stylesheet’ />”   
  220.                             + “</head>” + “<body>”);   
  221.             parser.setEncoding(parser.getEncoding());   
  222.             NodeList nodeList = null;   
  223.   
  224.             for (NodeIterator e = parser.elements(); e.hasMoreNodes();) {   
  225.                 Node node = e.nextNode();   
  226.                 logger   
  227.                         .fatal(”testLinkCSS()” + node.getText()   
  228.                                 + node.getClass());   
  229.   
  230.             }   
  231.         } catch (Exception e) {   
  232.             e.printStackTrace();   
  233.         }   
  234.     }   
  235.     /*  
  236.      * 测试OrFilter的用法  
  237.      */  
  238.     public void testOrFilter() {   
  239.         NodeFilter inputFilter = new NodeClassFilter(InputTag.class);   
  240.         NodeFilter selectFilter = new NodeClassFilter(SelectTag.class);   
  241.         Parser myParser;   
  242.         NodeList nodeList = null;   
  243.   
  244.         try {   
  245.             Parser parser = new Parser();   
  246.             parser   
  247.                     .setInputHTML(”<head><title>OrFilter Test</title>”   
  248.                             + “<link href=’/test01/css.css’ text=’text/css’ rel=’stylesheet’ />”   
  249.                             + “<link href=’/test02/css.css’ text=’text/css’ rel=’stylesheet’ />”   
  250.                             + “</head>”   
  251.                             + “<body>”   
  252.                             + “<input type=’text’ value=’text1′ name=’text1′/>”   
  253.                             + “<input type=’text’ value=’text2′ name=’text2′/>”   
  254.                             + “<select><option id=’1′>1</option><option id=’2′>2</option><option id=’3′></option></select>”   
  255.                             + “<a href=’http://www.yeeach.com’>yeeach.com</a>”   
  256.                             + “</body>”);   
  257.   
  258.             parser.setEncoding(parser.getEncoding());   
  259.             OrFilter lastFilter = new OrFilter();   
  260.             lastFilter.setPredicates(new NodeFilter[] { selectFilter,   
  261.                     inputFilter });   
  262.             nodeList = parser.parse(lastFilter);   
  263.             for (int i = 0; i <= nodeList.size(); i++) {   
  264.                 if (nodeList.elementAt(i) instanceof InputTag) {   
  265.                     InputTag tag = (InputTag) nodeList.elementAt(i);   
  266.                     logger.fatal(”OrFilter tag name is :” + tag.getTagName()   
  267.                             + ” ,tag value is:” + tag.getAttribute(”value”));   
  268.                 }   
  269.                 if (nodeList.elementAt(i) instanceof SelectTag) {   
  270.                     SelectTag tag = (SelectTag) nodeList.elementAt(i);   
  271.                     NodeList list = tag.getChildren();   
  272.   
  273.                     for (int j = 0; j < list.size(); j++) {   
  274.                         OptionTag option = (OptionTag) list.elementAt(j);   
  275.                         logger   
  276.                                 .fatal(”OrFilter Option”   
  277.                                         + option.getOptionText());   
  278.                     }   
  279.   
  280.                 }   
  281.             }   
  282.   
  283.         } catch (ParserException e) {   
  284.             e.printStackTrace();   
  285.         }   
  286.     }   
  287.     /*  
  288.      * 测试对<table><tr><td></td></tr></table>的解析  
  289.      */  
  290.     public void testTable() {   
  291.         Parser myParser;   
  292.         NodeList nodeList = null;   
  293.         myParser = Parser.createParser(”<body> ” + “<table id=’table1′ >”   
  294.                 + “<tr><td>1-11</td><td>1-12</td><td>1-13</td>”   
  295.                 + “<tr><td>1-21</td><td>1-22</td><td>1-23</td>”   
  296.                 + “<tr><td>1-31</td><td>1-32</td><td>1-33</td></table>”   
  297.                 + “<table id=’table2′ >”   
  298.                 + “<tr><td>2-11</td><td>2-12</td><td>2-13</td>”   
  299.                 + “<tr><td>2-21</td><td>2-22</td><td>2-23</td>”   
  300.                 + “<tr><td>2-31</td><td>2-32</td><td>2-33</td></table>”   
  301.                 + “</body>”, “GBK”);   
  302.         NodeFilter tableFilter = new NodeClassFilter(TableTag.class);   
  303.         OrFilter lastFilter = new OrFilter();   
  304.         lastFilter.setPredicates(new NodeFilter[] { tableFilter });   
分享到:
评论

相关推荐

    htmlparser 资料集合

    `htmlParser收集记录 - 记忆有问题!!! - CSDN博客.htm`和`HtmlParser初步研究 - lostfire - BlogJava.htm`这类博客文章,通常由开发者分享他们的学习心得和实践经验,可能包括一些常见问题的解决方法、技巧或最佳...

    HtmlParser

    网络爬虫,也称为网络蜘蛛或Web抓取器,是一种自动浏览互联网并收集信息的程序。它广泛应用于搜索引擎优化、数据分析、市场研究等多个领域。 在Python中,HTMLParser是内置的HTML解析器,它允许开发者编写自定义的...

    网络爬虫htmlparser

    在`endElement`中,我们处理完一个元素的内容,可能包括收集数据或结束数据的记录。 值得注意的是,网络爬虫在抓取数据时需要遵守网站的robots.txt协议,尊重网站的版权和用户隐私,避免过于频繁的请求导致服务器...

    基于htmlparser爬虫示例(图片).rar

    爬虫是互联网数据挖掘的重要工具,它能够自动遍历网页并收集相关信息。 首先,我们需要理解HTMLParser的基本工作原理。HTMLParser通过监听器模式来解析HTML,当遇到特定的HTML标签时,会触发相应的事件。例如,当...

    网络爬虫用堆栈队列贮存url

    网络爬虫是自动抓取网页信息的程序,它在互联网上遍历网页,收集所需数据。在实现网络爬虫时,高效地管理待抓取URL(统一资源定位符)是关键。这里,我们讨论如何使用堆栈和队列来优化这一过程。 首先,让我们了解...

    自己动手写网络爬虫用到的jar包

    网络爬虫是自动抓取网页信息的程序,它可以帮助我们高效地收集大量数据,用于数据分析、网站监控或搜索引擎构建等目的。在这个主题中,我们关注的是编写网络爬虫时可能会用到的一些关键Java库,这些库包含在提供的...

    针对淘宝的网络爬虫设计

    为了能够有效地收集这些信息,并构建起一套高效的信息搜索引擎,本项目设计并实现了一种专门针对淘宝网站的网络爬虫系统。 #### 二、关键技术与框架选择 ##### 1. HtmlParser - **概述**:此开源框架主要用于解析...

    Java编写的模拟网络爬虫的小程序

    网络爬虫是一种自动抓取互联网信息的程序,它按照一定的规则在网站上遍历网页,收集所需的数据。在Java编程语言中,实现一个简单的网络爬虫并不复杂,主要涉及到的技术包括HTTP请求、HTML解析、数据存储等。 1. **...

    c#主题蜘蛛,指定种子网站和主题词

    这种爬虫能够根据用户设定的“种子网站”(通常是某个或某些起始网页)和“主题词”(关键词或关键词集合)来搜索和收集相关信息。它的工作原理是遍历种子网站,并沿着网页间的链接扩展搜索范围,同时过滤和提取与...

    网络机器人编程指南(英文)

    这些智能代理能够在无需人工干预的情况下在网络上执行任务,如搜集特定主题的信息、在单一网站内检索信息,以及从多个来源收集数据并整合到单个页面上。书中不仅涵盖了基础的HTTP/网络编程知识,还深入探讨了如何...

    Python爬虫实现爬取百度百科词条功能实例

    在实例中,URL管理器维护了两个集合,`new_urls`用于存储待爬取的URL,`old_urls`记录已抓取的URL。当需要新的URL时,它会从`new_urls`中取出一个并转移到`old_urls`。 2. **网页下载器(UrlDownloader)**:从给定...

    delphi网页邮件抓发系统.zip

    这可能涉及DOM(Document Object Model)解析,如使用HTMLParser库,或者正则表达式匹配来提取特定格式的邮件地址。 4. **数据存储**:抓取到的邮件信息可能需要存储,这可能涉及到数据库操作,如SQLite、MySQL或...

    一个用java实现的抓取网站程序

    在IT领域,网络爬虫(spider)是一种用于自动化地从互联网上收集信息的程序。本项目是一个基于Java实现的网站抓取程序,利用多线程技术和HTML解析技术,同时具备防屏蔽功能,以高效、稳定的方式从目标网站获取数据。...

    java源码搜索链接Java网络爬虫(蜘蛛)源码-zhizhu

    在当今互联网时代,网络爬虫作为一种高效的数据收集工具,在大数据分析、搜索引擎优化、市场调研等多个领域发挥着重要作用。Java作为一门广泛应用于服务器端开发的语言,自然成为了构建网络爬虫系统的热门选择之一。...

    python使用tornado实现简单爬虫

    网络爬虫是自动收集网络信息的程序,它可以按照某种规则,自动地抓取互联网信息。而Tornado是一个Python开源的异步网络框架,适用于需要处理高并发的场景,非常适合用来编写网络爬虫程序。 首先,要使用Tornado框架...

    Wang-Kang/WebCrawler:在爬行过程中下载预先指定类型文件的网络爬虫。-matlab开发

    9. **日志记录**:为了便于调试和监控,爬虫应该有日志记录功能,记录爬取过程中的关键信息。 10. **数据存储**:下载的文件可能需要存储到本地文件系统或者数据库中,这涉及到了数据存储和组织策略。 总的来说,...

    java开源包1

    Flume 是一个分布式、可靠和高可用的服务,用于收集、聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型。这是一个可靠、容错的服务。 彩信发送开发包 apimms apimms 提供了各种语言用来发送彩信...

    java开源包11

    Flume 是一个分布式、可靠和高可用的服务,用于收集、聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型。这是一个可靠、容错的服务。 彩信发送开发包 apimms apimms 提供了各种语言用来发送彩信...

    java开源包2

    Flume 是一个分布式、可靠和高可用的服务,用于收集、聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型。这是一个可靠、容错的服务。 彩信发送开发包 apimms apimms 提供了各种语言用来发送彩信...

    java开源包3

    Flume 是一个分布式、可靠和高可用的服务,用于收集、聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型。这是一个可靠、容错的服务。 彩信发送开发包 apimms apimms 提供了各种语言用来发送彩信...

Global site tag (gtag.js) - Google Analytics