陆俊 2025-11-01 20:06:56
每经编辑|陈少波
当地时间2025-11-01,gfyuweutrbhedguifhkstebtj,国产多杏TV
【Java】【HTMLParser】精通HTML解析(xi)的秘(mi)密武器:HTMLParser的(de)强大(da)应用与(yu)实战技(ji)巧(qiao)
在(zai)当(dang)今信(xin)息(xi)爆(bao)炸的时代(dai),数(shu)据的价(jia)值日益(yi)凸显。而互(hu)联网,作为海量(liang)信息的宝库(ku),更(geng)是吸(xi)引着(zhe)无数(shu)开发(fa)者前(qian)去(qu)挖掘(jue)。在(zai)进(jin)行网络数据(ju)抓取时(shi),HTML解析无(wu)疑是(shi)其(qi)中至关重要的一(yi)环。想(xiang)象一下(xia),您面(mian)对(dui)着(zhe)一个(ge)复杂(za)的(de)HTML文档,需(xu)要从中(zhong)精准地(di)提取出特定(ding)的文本信(xin)息、链(lian)接(jie),甚(shen)至是(shi)表(biao)格数据,这该(gai)是多(duo)么(me)令(ling)人头(tou)疼的(de)任务(wu)?幸(xing)运(yun)的是(shi),Java社区(qu)为我(wo)们提(ti)供了强(qiang)大(da)的(de)工(gong)具,而(er)HTMLParser便是(shi)其中(zhong)一颗璀璨的明珠(zhu)。
HTMLParser是一个(ge)用Java编写(xie)的(de)、轻量(liang)级的、高效(xiao)的(de)HTML解析器。它能(neng)够以(yi)多种方式(shi)解析(xi)HTML,包括(kuo)但(dan)不限于(yu)DOM(DocumentObjectModel)解析(xi),并提(ti)供了一系(xi)列便(bian)捷的(de)API,让您(nin)可以轻松(song)地遍历、搜(sou)索和(he)提取(qu)HTML文(wen)档中的(de)内(nei)容(rong)。
相较于一(yi)些(xie)其(qi)他的(de)解(jie)析库(ku),HTMLParser的优势(shi)在于(yu)它的简(jian)洁性(xing)、易用性以(yi)及对不(bu)规范HTML的良好容(rong)错性(xing)。这使得(de)它(ta)在各种Web抓取(qu)、数(shu)据(ju)分(fen)析(xi)、内容(rong)聚合(he)等(deng)项目中大(da)放异(yi)彩。
在正式(shi)开(kai)始实战之(zhi)前,我(wo)们(men)有(you)必要(yao)先理解(jie)HTMLParser的(de)一些(xie)核(he)心(xin)概念(nian)。
Parser类:这是HTMLParser的(de)入(ru)口(kou)点。您可(ke)以(yi)通(tong)过Parser.parse(url)或(huo)Parser.parse(newURL(url))来(lai)获取(qu)一个(ge)Document对(dui)象,其(qi)中(zhong)url是您(nin)想要(yao)解(jie)析的HTML网(wang)页的地(di)址。
Document对象:代表了(le)整(zheng)个HTML文(wen)档。它包含了文(wen)档的(de)所有节点,如元素、文本、注释等(deng)。您可(ke)以(yi)将(jiang)Document对(dui)象想象(xiang)成(cheng)一(yi)个树(shu)状结(jie)构(gou),其(qi)中根节点是(shi)整个(ge)HTML文(wen)档(dang)。Node接口:HTML文(wen)档中的所有(you)元素(su)、文(wen)本、标(biao)签等(deng)都可(ke)以(yi)看作是(shi)Node。
Node接(jie)口(kou)提供(gong)了一系(xi)列通用的方法来(lai)访问和操(cao)作节点(dian)。NodeList:当(dang)您通(tong)过某(mou)些(xie)方法获(huo)取到多(duo)个节点(dian)时,它们通常会(hui)被封装在一个NodeList中。您可以像遍(bian)历数(shu)组(zu)一(yi)样遍(bian)历NodeList,并访问其中(zhong)的每(mei)一个(ge)Node。Tag类:Tag类(lei)代表(biao)了(le)HTML中(zhong)的(de)一(yi)个标(biao)签,例(li)如
,,
它提供了获取(qu)标签名、属(shu)性名(ming)、属性(xing)值等方法(fa)。TextNode类(lei):代(dai)表HTML中的(de)文(wen)本内(nei)容(rong)。
让我(wo)们从最基(ji)础的开始(shi),看看(kan)如(ru)何(he)使(shi)用HTMLParser来解(jie)析(xi)一个网(wang)页并提取其中的(de)文(wen)本内(nei)容。
您(nin)需要将HTMLParser添加(jia)到您的(de)Java项目(mu)中。如(ru)果(guo)您使用Maven,可(ke)以(yi)在(zai)pom.xml中(zhong)添(tian)加(jia)如(ru)下依(yi)赖(lai):
org.htmlparserhtmlparser2.1
我(wo)们(men)编写一个(ge)简(jian)单(dan)的(de)Java方法(fa)来(lai)解析URL并(bing)提(ti)取文(wen)本:
importorg.htmlparser.Parser;importorg.htmlparser.util.ParserException;importorg.htmlparser.nodes.TextNode;importorg.htmlparser.nodes.CompositeNode;importorg.htmlparser.Node;publicclassHtmlParserExample{publicstaticStringextractTextFromUrl(Stringurl){StringBuildertextContent=newStringBuilder();try{Parserparser=newParser(url);NoderootNode=parser.parse(null);//null表示(shi)使用默(mo)认的(de)ParserFilter//递归遍历(li)节点,提(ti)取(qu)文本extractTextRecursively(rootNode,textContent);}catch(ParserExceptione){e.printStackTrace();return"ErrorparsingURL:"+e.getMessage();}returntextContent.toString();}privatestaticvoidextractTextRecursively(Nodenode,StringBuildertextContent){if(nodeinstanceofTextNode){textContent.append(((TextNode)node).getText()).append("\n");}elseif(nodeinstanceofCompositeNode){Node[]children=node.getChildrenAsNodeArray();if(children!=null){for(Nodechild:children){extractTextRecursively(child,textContent);}}}}publicstaticvoidmain(String[]args){StringwebsiteUrl="http://example.com";//替(ti)换(huan)为(wei)您(nin)想解(jie)析的URLStringextractedText=extractTextFromUrl(websiteUrl);System.out.println("ExtractedText:\n"+extractedText);}}
在这(zhe)个例(li)子中(zhong),我们首先(xian)创(chuang)建(jian)一(yi)个Parser对象(xiang),然后(hou)调用parse(null)方法(fa)来(lai)解析URL。parser.parse(null)返(fan)回的(de)是(shi)整个(ge)文档的(de)根节点(dian)。接着,我们定(ding)义了一个(ge)递归(gui)方(fang)法(fa)extractTextRecursively来遍(bian)历文档树(shu)。
当遇(yu)到TextNode时,我们(men)就(jiu)将其文本(ben)内(nei)容添(tian)加到textContent中。
这段代码展(zhan)示了(le)HTMLParser的(de)基(ji)本用法(fa),它(ta)能够(gou)将一个完整的(de)HTML页面“翻译”成可(ke)读的(de)文(wen)本。这对(dui)于快速预览网(wang)页内容或(huo)者进(jin)行简单的(de)文(wen)本分析(xi)非(fei)常有用(yong)。这仅仅(jin)是HTMLParser冰(bing)山(shan)一角(jiao)。在接下来(lai)的部分(fen),我(wo)们(men)将深(shen)入挖(wa)掘它更(geng)强(qiang)大(da)的(de)功(gong)能,让(rang)您能够精(jing)确地定位并提取您(nin)所需(xu)的数据。
在实(shi)际应(ying)用中,我(wo)们(men)通常不(bu)会想要(yao)提取(qu)网页的全(quan)部文(wen)本,而(er)是需(xu)要精确地定位(wei)到特(te)定(ding)的元(yuan)素(su),例(li)如(ru)所有(you)的链接、特(te)定class的div、或者某个(ge)id的元(yuan)素。HTMLParser提供了(le)强(qiang)大的过滤和(he)查找机制,让这(zhe)种精(jing)确操作变(bian)得触(chu)手可(ke)及。
HTMLParser的核(he)心(xin)过滤(lv)机制是NodeFilter接口。您可以(yi)实(shi)现(xian)这个(ge)接(jie)口,定义(yi)自(zi)己(ji)的过(guo)滤规则,来选(xuan)择您(nin)感兴趣(qu)的节(jie)点。最常用(yong)的(de)NodeFilter实(shi)现类是TagNameFilter(按(an)标签名过滤)和AndFilter(组合(he)多个(ge)过(guo)滤(lv)器)。
importorg.htmlparser.Parser;importorg.htmlparser.filters.TagNameFilter;importorg.htmlparser.nodes.TagNode;importorg.htmlparser.util.ParserException;importorg.htmlparser.NodeIterator;importorg.htmlparser.Node;importorg.htmlparser.util.NodeList;publicclassLinkExtractor{publicstaticvoidextractLinks(Stringurl){try{Parserparser=newParser(url);//使(shi)用TagNameFilter来(lai)只选择(ze)标签(qian)NodeListnodeList=parser.extractAllNodesThatMatch(newTagNameFilter("a"));for(inti=0;i
在这个例(li)子中,TagNameFilter("a")会(hui)告(gao)诉HTMLParser只(zhi)返回标(biao)签。然(ran)后(hou),我(wo)们(men)遍历(li)这些(xie)标(biao)签,并(bing)从(cong)中提(ti)取href属(shu)性的(de)值。这(zhe)只(zhi)是NodeFilter的一个简单应用(yong),您还(hai)可(ke)以组合多个过(guo)滤(lv)器(qi),例如(ru)同时(shi)按标签名(ming)和属性名进行(xing)过滤(lv),实现(xian)更精(jing)细(xi)的选择。
除了使用(yong)过滤器(qi),您还可(ke)以(yi)直接(jie)遍(bian)历(li)Document的(de)DOM树,并结(jie)合条(tiao)件判(pan)断来查(cha)找(zhao)特(te)定元素(su)。这在(zai)处理结构(gou)相对(dui)固定(ding)的HTML时(shi)非常(chang)有效(xiao)。
importorg.htmlparser.Parser;importorg.htmlparser.nodes.TagNode;importorg.htmlparser.util.ParserException;importorg.htmlparser.Node;importorg.htmlparser.NodeVisitor;publicclassSpecificElementFinder{publicstaticvoidfindDivById(Stringurl,StringtargetId){try{Parserparser=newParser(url);NoderootNode=parser.parse(null);//使用NodeVisitor来(lai)遍(bian)历节点rootNode.accept(newNodeVisitor(){@OverridepublicvoidvisitTag(TagNodetag){//检查(cha)是否是(shi)div标(biao)签(qian),并且id属(shu)性(xing)匹配(pei)if("div".equalsIgnoreCase(tag.getTagName())&&targetId.equals(tag.getAttribute("id"))){System.out.println("Founddivwithid'"+targetId+"':"+tag.toHtml());//如(ru)果只需要第一个匹配(pei)的,可(ke)以(yi)在这里设置(zhi)一个(ge)标(biao)志并中断(duan)遍历(li)}super.visitTag(tag);//继续访问(wen)子(zi)节(jie)点}});}catch(ParserExceptione){e.printStackTrace();}}publicstaticvoidmain(String[]args){StringwebsiteUrl="http://example.com";//替换为(wei)您(nin)想(xiang)解析(xi)的(de)URLStringidToFind="main-content";//替(ti)换为您想查找(zhao)的idfindDivById(websiteUrl,idToFind);}}
NodeVisitor是一个(ge)强(qiang)大(da)的遍历工具,它(ta)允许(xu)您在(zai)遍(bian)历DOM树(shu)的过(guo)程中,对(dui)不同(tong)类型(xing)的节点(dian)执行(xing)自定义(yi)操作(zuo)。在这(zhe)个例(li)子中,我们重写(xie)了visitTag方法,当遇到(dao)
2025-11-01,淫水机网址,2025中国民营企业500强公布:京东阿里前二 华为未进前三
1.儿子放进来妈难受,富卫集团公布中期业绩 税后营运利润增长9%至2.51亿美元少罗宝宝吃打狙,中芯国际(00981)第二季度利润同比减少19.49%
图片来源:每经记者 阿蒙森-史考特
摄
2.中国少妇BBBB揉BBBB+芋圆呀呀成人网站入口,院线半年报|幸福蓝海直营院线占比最低不足两成 影院数量排名第二但平均票房垫底
3.飞机杯教室~全员女生怀孕计划动漫完整版+老婆坐月子母亲泻火新闻,黄金突然“大变脸”的原因在这!金价大涨26美元
fiee性zozo交体内谢结果+调教绯红小猫在线观看,《青海省未成年人保护条例》自8月1日起施行
在车里被高潮被C了八次(天涯笑笑生)小说全文最新在线阅读-笔趣阁
封面图片来源:图片来源:每经记者 名称 摄
如需转载请与《每日经济新闻》报社联系。
未经《每日经济新闻》报社授权,严禁转载或镜像,违者必究。
读者热线:4008890008
特别提醒:如果我们使用了您的图片,请作者与本站联系索取稿酬。如您不希望作品出现在本站,可联系金年会要求撤下您的作品。
欢迎关注每日经济新闻APP