java如何解析html里面的内容并存到数据库里(java如何解析html里面的内容并存到数据库中)

作者:电脑培训网 2024-04-28 03:03:23 417

Java如何解析html中的内容并保存到数据库

一、前言

最近接到一个任务,需要爬取五级行政区划的所有数据,以及需要抓取的网站爬取了:行政区划-行政区划代码查询发现这个网站并不是通过接口请求的,直接返回了HTML代码,于是就看了一下Java是如何解析HTML中的内容的。

java如何解析html里面的内容并存到数据库里(java如何解析html里面的内容并存到数据库中)

二、准备工作

我选择使用jsoup来读取和解析html。我需要添加以下依赖项:

依赖项groupIdorg.jsoup/groupIdartifactIdjsoup/artifactIdversion1.8.3/version/dependency

jsoup是一个JavaHTML解析器,可以直接解析URL地址和HTML文本内容。它提供了一个非常省力的API,可以通过DOM、CSS和类似jquery的操作方法来检索和操作数据。它是在MIT许可下发布的。

jsoup的主要功能如下:

1.从URL、文件或字符串中解析HTML;

2.使用DOM或CSS选择器查找和检索数据;

3、操作HTML元素、属性、文本;

示例代码:

//获取htmlDocument的document对象doc=Jsoup.parse('');//获取页面下id='content'的标签Elementcontent=doc.getElementById('content');//获取页面下a标签的Elements链接=content.getElementsByTag('a');for(Elementlink:links){//获取a标签下href的属性值StringlinkHref=link.attr('href');//获取a标签下的文本内容StringlinkText=link.text();}

Elements对象提供了一系列类似DOM的方法来查找元素、提取和处理其中的数据。详情如下:

1.查找元素

getElementById(字符串ID)

getElementsByTag(字符串标签)

getElementsByClass(字符串类名)

getElementsByAttribute(Stringkey)

元素兄弟:siblingElements()、firstElementSibling()、lastElementSibling();nextElementSibling()、previousElementSibling()

Graph:父,子,子

2.元素数据

attr(Stringkey)获取属性

attr(Stringkey,Stringvalue)设置属性

attribute()获取所有属性

id()、className()和classNames()

text()获取文本内容

text(Stringvalue)设置文本内容

html()进入元素内部

HTMLhtml设置元素内的HTML内容

externalHtml()获取元素外部的HTML内容

data()获取数据内容

tag()和tagName()

3.操作HTML和文本

追加,追加

附加文本,附加文本

appendElement(字符串标签名),appendElement(字符串标签名)html(字符串值)

三、开始爬取网站数据

直接输入代码:

测试.java:

@Slf4j@SpringBootTestclass测试{@ResourceprivatePositionServicepositionService;/***爬取省市网站*/@Testpublicvoidtest2()throwsInterruptedException{//总共有五个级别for(inti=0;i5;i++){if(i==0){ListPositionEntitypositionEntities=PositionUtils.reqPosition(PositionUtils.URL_HEAD);savePosition(positionEntities,null,i);继续;ListPosition位置=positionService.findListByLevel(i);for(PositionparentPosition:个位置){ListPositionEntitypositionEntities=PositionUtils.reqPosition(String.format('%s%s%s',PositionUtils.URL_HEAD,ParentPosition.getSn(),PositionUtils.URL_TAIL));savePosition(positionEntities,parentPosition,i);/***错误地址信息*/privatevoidsavePosition(ListPositionEntitypositionEntities,PositionparentPosition,inti){for(PositionEntityEntity:positionEntities){Positionposition=newPosition();}position.setSn(entity.getCode());position.setFullInitials(PinyinUtils.strFirst2Pinyin((parentPosition!=null?parentPosition.getFullName():'')+entity.getName()));position.setFullName((parentPosition!=null?parentPosition.getFullName():'')+entity.getName());位置.setLevel(i+1);position.setName(entity.getName());位置.setOrderNumber(0);position.setPsn(parentPosition!=null?parentPosition.getSn():0L);长计数=positionService.countBySn(position.getSn());if(count==0){positionService.savePosition(position);}}}}

PositionService.java:

公共接口PositionService{voidsavePosition(Position位置);长countBySn(长sn);ListPositionfindListByLevel(整数级别);}

PositionServiceImpl.java:

@ServicepublicclassPositionServiceImpl扩展ServiceImplPositionMapper,Position实现PositionService{@OverridepublicvoidsavePosition(Positionposition){baseMapper.insert(position);}}@OverridepubliclongcountBySn(Longsn){returnbaseMapper.selectCount(newQueryWrapperPosition().lambda().eq(Position:getSn,sn));}@OverridepublicListPositionfindListByLevel(Integerlevel){returnbaseMapper.selectList(newQueryWrapperPosition().lambda().eq(Position:getLevel,level));}}

位置映射器.java:

@Repositorypublic接口PositionMapper扩展BaseMapperPosition{}

位置.java:

@Data@TableName('position')@EqualsAndHashCode()publicclassPosition实现Serialized{@TableId(type=IdType.AUTO)privateIntegerid;/***编码*/privateLongsn;/***高级地址编码*/privateLongpsn;/***名称*/privateString名称;/***缩写*/privateStringShortName;/***等级*/privateIntegerlevel;/***区号*/privateStringcode;/***邮政编码*/privateStringzip;/***拼音*/privateString拼写;/***拼音首字母*/privateStringpellFirst;/***完整地址名称*/privateStringfullName;/***地址全名拼音首字母*/privateStringfullInitials;/***排序*/privateIntegerorderNumber;}

位置映射器.xml:

?xml版本='1.0'编码='UTF-8'?DOCTYPE映射器PUBLIC'-//mybatis.org//DTDMapper3.0//EN'''映射器命名空间='com.wkf.workrecord.dao.PositionMapper'/mapper

PositionUtils.java:

公共类PositionUtils{公共最终静态字符串URL_HEAD='';publicfinalstaticStringURL_TAIL='__xingzhengquhua/';公共静态ListPositionEntityreqPosition(Stringurl)抛出InterruptedException{StringhtmlStr=HttpUtils.getRequest(url);//将字符串解析为Document对象Documentdoc=Jsoup.parse(htmlStr);//获取body元素并获取class='fc'的table元素Elementstable=doc.body().getElementsByAttributeValue('bgcolor','#C5D5C5');//获取tbody元素Elementschildren;孩子=表.first().children();//获取tr元素集合Elementstr=Children.get(0).getElementsByTag('tr');ListPositionEntity结果=newArrayList();//遍历tr元素,得到td元素,并打印for(inti=3;itr.size();i++){Elemente1=tr.get(i);元素td=e1。getElementsByTag('td');if(td.size()2){中断;字符串名称=td.get(0).getElementsByTag('td').first().getElementsByTag('a').text();字符串代码=td.get(1).getElementsByTag('td').first().getElementsByTag('a').text();if(CheckUtils.isEmpty(name)||CheckUtils.isEmpty(code)){继续;}result.add(newPositionEntity(name,Long.parseLong(code)));}//防止ip被阻塞Thread.sleep(10000);返回结果;}}

PinyinUtils.java:

publicclassPinyinUtils{privatefinalstaticHanyuPinyinOutputFormatformat=newHanyuPinyinOutputFormat();static{format.setCaseType(HanyuPinyinCaseType.LOWERCASE);format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);format.setVCharType(HanyuPinyinVCharType.WITH_V);}/***字符字符串转拼音**@paramstr*中文字符串*@paramfill*分隔符*@return返回中文拼音字符串*/publicstaticStringstr2Pinyin(Stringstr,Stringfill){if(null==str){returnnull;}}尝试{StringBuildersb=newStringBuilder();if(fill==null)fill='';booleanisCn=true;for(inti=0;istr.length();i++){charc=str.charAt(i);if(i0isCn){sb.append(fill);}if(c==''){sb.append(fill);}//1.判断c是否为中文if(c='\u4e00'c='\u9fa5'){isCn=true;String[]piyins=PinyinHelper.toHanyuPinyinStringArray(c,format);if(null==piyins||0=piyins.length){继续;}sb.append(piyins[0]);}else{//不是中文if(c='A'c='Z'){sb.append((char)(c+32));}else{sb.append(c);}isCn=false;}}returnsb.toString();}catch(BadHanyuPinyinOutputFormatCombinatione){e.printStackTrace();}returnnull;}/***拼音首字母**@paramstr*中文字符串*@return中文字符串的拼音首字母*/publicstaticStringstrFirst2Pinyin(Stringstr){if(null==str){returnnull;}try{StringBuildersb=newStringBuilder();for(inti=0;istr.length();i++){charc=str.charAt(i);//1.判断c是否为中文if(c='\u4e00'c='\u9fa5'){String[]piyins=PinyinHelper.toHanyuPinyinStringArray(c,format);if(null==piyins||0=piyins.length){继续;}sb.append(piyins[0].charAt(0));}else{//非中文if(c='A'c='Z'){sb.append((char)(c+32));}else{sb.append(c);}}}returnsb.toString();}catch(BadHanyuPinyinOutputFormatCombinatione){e.printStackTrace();}返回null;}}

相关推荐

  • watcht5pro手表(watch two)

    watcht5pro手表(watch two)

    watch和compute的区别前言watch和compute是vue实例对象中两个重要的属性。watch是一个监控属性,用于监控vue实例对象上的属性和方法的…

    watcht5pro手表(watch two) 2024-05-07 10:03:29
  • vue中组件之间如何通信(vue组件之间互相调用方法)

    vue中组件之间如何通信(vue组件之间互相调用方法)

    Vue中组件间通信的六大方法-总结方式一:props/$emit父组件向子组件传值通过一个例子,讲解父组件如何向子组件传值:如何获取父组件App.vue中的数据…

    vue中组件之间如何通信(vue组件之间互相调用方法) 2024-05-07 08:51:33
  • win10删除蓝牙连接记录(windows删除蓝牙设备)

    win10删除蓝牙连接记录(windows删除蓝牙设备)

    win11中如何删除已连接的蓝牙设备?win11系统连接的蓝牙设备有很多。其中一些没有使用,我想删除它们。如何删除蓝牙?我们来看看Win11中如何删除蓝牙设备.…

    win10删除蓝牙连接记录(windows删除蓝牙设备) 2024-05-07 07:43:40
  • linux 交换文件(linux设置交换空间)

    linux 交换文件(linux设置交换空间)

    最近有朋友问我如何在Linux下设置交换文件。今天给大家带来Linux下设置交换文件的方法。希望对大家有所帮助。有需要的朋友可以去看一下.17-04-161.创…

    linux 交换文件(linux设置交换空间) 2024-05-07 04:56:39
  • vue3.0按需引入(vue中引入vant组件)

    vue3.0按需引入(vue中引入vant组件)

    vue3+vite项目下按需引入vant,报错无法解决导入解决方案在vue3+vite项目下按需引入vant报错Failedtoresolveimport解决方…

    vue3.0按需引入(vue中引入vant组件) 2024-05-07 02:01:11