陈观玉 2025-11-01 23:53:31
每经编辑|陈朝宗
当地时间2025-11-01,gfyuweutrbhedguifhkstebtj,文轩体育课器材室河马
【Java】【HTMLParser】精(jing)通HTML解析(xi)的秘(mi)密武器:HTMLParser的强大(da)应用与(yu)实(shi)战技(ji)巧
在(zai)当(dang)今信息爆炸的(de)时(shi)代,数(shu)据的(de)价值(zhi)日益(yi)凸显。而互(hu)联(lian)网,作为(wei)海量信息的宝(bao)库(ku),更(geng)是(shi)吸(xi)引(yin)着无数开发(fa)者前去(qu)挖掘(jue)。在进行网络(luo)数据(ju)抓取(qu)时,HTML解(jie)析无疑(yi)是(shi)其(qi)中至(zhi)关(guan)重要的一(yi)环。想(xiang)象一下(xia),您(nin)面对(dui)着一(yi)个(ge)复(fu)杂的(de)HTML文档,需要从中(zhong)精准地提取出(chu)特定(ding)的(de)文本信(xin)息、链接,甚至是(shi)表格(ge)数(shu)据(ju),这该是多(duo)么(me)令(ling)人头(tou)疼的(de)任务?幸运的是,Java社区为(wei)我们提(ti)供(gong)了强大(da)的工(gong)具(ju),而HTMLParser便是(shi)其中一颗(ke)璀璨的(de)明珠。
HTMLParser是(shi)一个用(yong)Java编写(xie)的、轻量(liang)级的、高效的HTML解(jie)析器(qi)。它能(neng)够以多种方(fang)式解析HTML,包(bao)括(kuo)但不限于(yu)DOM(DocumentObjectModel)解析,并提(ti)供了(le)一系(xi)列(lie)便捷的(de)API,让您(nin)可以(yi)轻(qing)松地(di)遍历、搜索和(he)提(ti)取(qu)HTML文档(dang)中(zhong)的内容。
相较于一(yi)些其(qi)他(ta)的解(jie)析(xi)库,HTMLParser的(de)优势(shi)在于(yu)它(ta)的简洁性、易(yi)用性以及对不(bu)规范HTML的良(liang)好容错(cuo)性(xing)。这(zhe)使(shi)得它(ta)在各(ge)种(zhong)Web抓取、数(shu)据(ju)分析(xi)、内(nei)容聚(ju)合(he)等项(xiang)目中(zhong)大(da)放(fang)异彩(cai)。
在(zai)正式开(kai)始(shi)实(shi)战之(zhi)前(qian),我(wo)们(men)有必要(yao)先理解HTMLParser的(de)一些核心(xin)概念(nian)。
Parser类:这(zhe)是HTMLParser的入口(kou)点。您可以(yi)通过(guo)Parser.parse(url)或Parser.parse(newURL(url))来(lai)获取(qu)一个(ge)Document对象(xiang),其中url是您(nin)想要(yao)解析(xi)的HTML网(wang)页的地(di)址(zhi)。
Document对(dui)象(xiang):代表(biao)了整个HTML文(wen)档。它(ta)包(bao)含了文(wen)档的(de)所有(you)节点(dian),如元(yuan)素、文(wen)本、注(zhu)释等。您可以将Document对象想象(xiang)成一(yi)个树状(zhuang)结构,其中根节点是整个(ge)HTML文档。Node接口:HTML文(wen)档中的(de)所有元(yuan)素、文本(ben)、标签等都可以(yi)看作是(shi)Node。
Node接口(kou)提(ti)供了一(yi)系列通用(yong)的方(fang)法(fa)来(lai)访(fang)问和(he)操(cao)作(zuo)节(jie)点。NodeList:当(dang)您通(tong)过某(mou)些(xie)方(fang)法获(huo)取到(dao)多个节点(dian)时(shi),它(ta)们通常会(hui)被封(feng)装在(zai)一个NodeList中。您(nin)可以像遍(bian)历数组(zu)一(yi)样遍(bian)历NodeList,并(bing)访(fang)问其中(zhong)的每(mei)一个(ge)Node。Tag类(lei):Tag类代表了(le)HTML中的一个标签,例如
,,
它提供了获取(qu)标签名、属(shu)性名、属(shu)性(xing)值(zhi)等方法(fa)。TextNode类:代表HTML中(zhong)的(de)文(wen)本内容。
让(rang)我们从(cong)最基础(chu)的(de)开始(shi),看看(kan)如(ru)何使用HTMLParser来(lai)解(jie)析一个(ge)网页并提(ti)取(qu)其(qi)中(zhong)的文(wen)本内容。
您需要将HTMLParser添(tian)加到您的(de)Java项目中。如果您使用(yong)Maven,可以在pom.xml中(zhong)添加如(ru)下(xia)依赖:
org.htmlparserhtmlparser2.1
我们(men)编写一个简单(dan)的Java方法来(lai)解析(xi)URL并提(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表示使用默(mo)认的(de)ParserFilter//递归(gui)遍历(li)节点,提取文本(ben)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";//替换为您(nin)想解(jie)析的URLStringextractedText=extractTextFromUrl(websiteUrl);System.out.println("ExtractedText:\n"+extractedText);}}
在(zai)这(zhe)个(ge)例(li)子中,我们(men)首先(xian)创建(jian)一(yi)个(ge)Parser对象,然后(hou)调用parse(null)方法(fa)来(lai)解析URL。parser.parse(null)返回的(de)是整(zheng)个文档的根(gen)节点(dian)。接着(zhe),我(wo)们定(ding)义(yi)了一个(ge)递归方法(fa)extractTextRecursively来遍(bian)历(li)文档(dang)树。
当遇(yu)到(dao)TextNode时(shi),我(wo)们(men)就将其文本(ben)内(nei)容添(tian)加(jia)到textContent中(zhong)。
这(zhe)段(duan)代码展示了HTMLParser的基本用(yong)法,它能(neng)够(gou)将一个(ge)完整的(de)HTML页面“翻译(yi)”成可读的(de)文(wen)本(ben)。这对于快速预览网(wang)页(ye)内(nei)容(rong)或者进(jin)行简(jian)单(dan)的文本分析非(fei)常有用(yong)。这仅(jin)仅是HTMLParser冰山(shan)一(yi)角。在(zai)接(jie)下(xia)来(lai)的部(bu)分,我(wo)们将(jiang)深入挖(wa)掘它更(geng)强大的功(gong)能,让(rang)您能够(gou)精确地(di)定位(wei)并提取您(nin)所(suo)需的(de)数(shu)据(ju)。
在(zai)实际应(ying)用中,我们通常(chang)不会想要(yao)提取(qu)网页(ye)的全部文(wen)本,而(er)是需(xu)要精确地定位到特(te)定的元素,例如所有(you)的链接、特(te)定(ding)class的(de)div、或(huo)者(zhe)某(mou)个id的元素(su)。HTMLParser提(ti)供了(le)强大的(de)过(guo)滤和查找(zhao)机制,让这(zhe)种精确操作变(bian)得触(chu)手(shou)可及(ji)。
HTMLParser的核心(xin)过(guo)滤(lv)机制(zhi)是NodeFilter接口。您(nin)可(ke)以(yi)实现这(zhe)个(ge)接口(kou),定(ding)义(yi)自(zi)己的过(guo)滤规则,来选择(ze)您感(gan)兴趣的节(jie)点(dian)。最常用(yong)的NodeFilter实现类(lei)是TagNameFilter(按标签(qian)名过(guo)滤)和(he)AndFilter(组合(he)多个(ge)过滤器)。
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)标签NodeListnodeList=parser.extractAllNodesThatMatch(newTagNameFilter("a"));for(inti=0;i
在(zai)这个例(li)子中,TagNameFilter("a")会告诉HTMLParser只(zhi)返回(hui)标签(qian)。然后(hou),我(wo)们(men)遍(bian)历这些(xie)标签(qian),并从中提取(qu)href属(shu)性(xing)的(de)值(zhi)。这(zhe)只是NodeFilter的一(yi)个简单应用(yong),您(nin)还可(ke)以组(zu)合多(duo)个过滤(lv)器(qi),例如同时(shi)按标签名和属(shu)性名进行过滤(lv),实现更(geng)精细的(de)选择(ze)。
除(chu)了(le)使用过滤器(qi),您还可以(yi)直接(jie)遍历(li)Document的DOM树(shu),并结(jie)合(he)条件判(pan)断来(lai)查找(zhao)特(te)定(ding)元(yuan)素(su)。这在处理结(jie)构相(xiang)对固定(ding)的HTML时(shi)非常(chang)有(you)效(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);//使用(yong)NodeVisitor来(lai)遍历节点rootNode.accept(newNodeVisitor(){@OverridepublicvoidvisitTag(TagNodetag){//检(jian)查(cha)是否是div标(biao)签,并且id属性(xing)匹(pi)配if("div".equalsIgnoreCase(tag.getTagName())&&targetId.equals(tag.getAttribute("id"))){System.out.println("Founddivwithid'"+targetId+"':"+tag.toHtml());//如(ru)果只需要第(di)一(yi)个匹(pi)配(pei)的,可以(yi)在(zai)这(zhe)里设(she)置一个(ge)标志并(bing)中断遍历}super.visitTag(tag);//继(ji)续访问(wen)子节(jie)点(dian)}});}catch(ParserExceptione){e.printStackTrace();}}publicstaticvoidmain(String[]args){StringwebsiteUrl="http://example.com";//替(ti)换为(wei)您想解(jie)析的URLStringidToFind="main-content";//替(ti)换为(wei)您(nin)想(xiang)查找(zhao)的idfindDivById(websiteUrl,idToFind);}}
NodeVisitor是一个(ge)强(qiang)大(da)的遍历(li)工具,它(ta)允许您在(zai)遍历(li)DOM树的(de)过(guo)程(cheng)中,对(dui)不同(tong)类型的节(jie)点执(zhi)行(xing)自定义(yi)操作(zuo)。在(zai)这个例(li)子中(zhong),我们(men)重(zhong)写(xie)了visitTag方法(fa),当遇(yu)到
2025-11-01,黑闰润付费内容包括哪些内容,美元前景取决于海外资金:政策不确定或抑制美债需求,市场聚焦本周CPI
1.当你的臭脚老婆抖音风混剪在线观看,PCB企业加码布局高端产能少女与狗2第2部免费播放,告别“手续费价格战”!期货业将迎“反内卷”新规,设两个月过渡期
图片来源:每经记者 阮树强
摄
2.千禧试机号金码今天的+男女插进去软件,金山软件(03888)中期股东溢利同比增长20.41% 不派中期股息
3.流鼻血A站+3q经过详细讲述,宏工科技:公司高度重视股东回报的持续性与合理性
抖阴污软件下载+靠逼的直播,德新科技:上半年归母净利润同比增长187.09%
洞察新知!拉拉炒菜教程网站.详细解答、解释与落实发现绳艺的无穷
封面图片来源:图片来源:每经记者 名称 摄
如需转载请与《每日经济新闻》报社联系。
未经《每日经济新闻》报社授权,严禁转载或镜像,违者必究。
读者热线:4008890008
特别提醒:如果我们使用了您的图片,请作者与本站联系索取稿酬。如您不希望作品出现在本站,可联系金年会要求撤下您的作品。
欢迎关注每日经济新闻APP