Java怎么解析html中的内容并存到数据库

前端开发   发布日期:2024年05月07日   浏览次数:594

这篇文章主要讲解了“Java怎么解析html中的内容并存到数据库”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java怎么解析html中的内容并存到数据库”吧!

准备工作

我选用的是使用jsoup进行html的读取和解析,需要加入如下依赖:

  1. <dependency>
  2. <groupId>org.jsoup</groupId>
  3. <artifactId>jsoup</artifactId>
  4. <version>1.8.3</version>
  5. </dependency>

jsoup 是一款 Java 的HTML 解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jquery的操作方法来取出和操作数据。它是基于MIT协议发布的。

jsoup的主要功能如下:

1、从一个URL,文件或字符串中解析HTML;

2、使用DOM或CSS选择器来查找、取出数据;

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

示例代码:

  1. //获取html的文档对象
  2. Document doc = Jsoup.parse("http://www.dangdang.com");
  3. //获取页面下id="content"的标签
  4. Element content = doc.getElementById("content");
  5. //获取页面下的a标签
  6. Elements links = content.getElementsByTag("a");
  7. for (Element link : links) {
  8. //获取a标签下的href的属性值
  9. String linkHref = link.attr("href");
  10. //获取a标签下的文本内容
  11. String linkText = link.text();
  12. }

Elements这个对象提供了一系列类似于DOM的方法来查找元素,抽取并处理其中的数据。具体如下:

1、查找元素

getElementById(String id)

getElementsByTag(String tag)

getElementsByClass(String className)

getElementsByAttribute(String key) (and related methods)

Element siblings: siblingElements(), firstElementSibling(), lastElementSibling();nextElementSibling(), previousElementSibling()

Graph: parent(), children(), child(int index)

2、元素数据

attr(String key)获取属性

attr(String key, String value)设置属性

attributes()获取所有属性

id(), className() and classNames()

text()获取文本内容

text(String value) 设置文本内容

html()获取元素内

HTMLhtml(String value)设置元素内的HTML内容

outerHtml()获取元素外HTML内容

data()获取数据内容(例如:script和style标签)

tag() and tagName()

3、操作HTML和文本

append(String html), prepend(String html)

appendText(String text), prependText(String text)

appendElement(String tagName), prependElement(String tagName) html(String value)

开始爬取网站数据

直接上代码:

Test.java:

  1. @Slf4j
  2. @SpringBootTest
  3. class Test {
  4. @Resource
  5. private PositionService positionService;
  6. /**
  7. * 爬取省市区网站
  8. */
  9. @Test
  10. public void test2() throws InterruptedException {
  11. //一共五级
  12. for (int i = 0 ; i < 5 ; i++) {
  13. if (i == 0) {
  14. List<PositionEntity> positionEntities = PositionUtils.reqPosition(PositionUtils.URL_HEAD);
  15. savePosition(positionEntities, null, i);
  16. continue;
  17. }
  18. List<Position> positions = positionService.findListByLevel(i);
  19. for (Position parentPosition : positions) {
  20. List<PositionEntity> positionEntities = PositionUtils.reqPosition(String.format("%s%s%s", PositionUtils.URL_HEAD, parentPosition.getSn(), PositionUtils.URL_TAIL));
  21. savePosition(positionEntities, parentPosition, i);
  22. }
  23. }
  24. }
  25. /**
  26. * 报错地址信息
  27. */
  28. private void savePosition(List<PositionEntity> positionEntities, Position parentPosition, int i){
  29. for (PositionEntity entity : positionEntities) {
  30. Position position = new Position();
  31. position.setSn(entity.getCode());
  32. position.setFullInitials(PinyinUtils.strFirst2Pinyin((parentPosition != null ? parentPosition.getFullName() : "")+entity.getName()));
  33. position.setFullName((parentPosition != null ? parentPosition.getFullName() : "")+entity.getName());
  34. position.setLevel(i + 1);
  35. position.setName(entity.getName());
  36. position.setOrderNumber(0);
  37. position.setPsn(parentPosition != null ? parentPosition.getSn() : 0L);
  38. long count = positionService.countBySn(position.getSn());
  39. if (count == 0) {
  40. positionService.savePosition(position);
  41. }
  42. }
  43. }
  44. }

PositionService.java:

  1. public interface PositionService {
  2. void savePosition(Position position);
  3. long countBySn(Long sn);
  4. List<Position> findListByLevel(Integer level);
  5. }

PositionServiceImpl.java:

  1. @Service
  2. public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements PositionService {
  3. @Override
  4. public void savePosition(Position position) {
  5. baseMapper.insert(position);
  6. }
  7. @Override
  8. public long countBySn(Long sn) {
  9. return baseMapper.selectCount(new QueryWrapper<Position>().lambda().eq(Position::getSn, sn));
  10. }
  11. @Override
  12. public List<Position> findListByLevel(Integer level) {
  13. return baseMapper.selectList(new QueryWrapper<Position>().lambda().eq(Position::getLevel, level));
  14. }
  15. }

PositionMapper.java:

  1. @Repository
  2. public interface PositionMapper extends BaseMapper<Position> {
  3. }

Position.java:

  1. @Data
  2. @TableName("position")
  3. @EqualsAndHashCode()
  4. public class Position implements Serializable {
  5. @TableId(type = IdType.AUTO)
  6. private Integer id;
  7. /**
  8. * 编码
  9. */
  10. private Long sn;
  11. /**
  12. * 上级地址编码
  13. */
  14. private Long psn;
  15. /**
  16. * 名称
  17. */
  18. private String name;
  19. /**
  20. * 简称
  21. */
  22. private String shortName;
  23. /**
  24. * 层级
  25. */
  26. private Integer level;
  27. /**
  28. * 区号
  29. */
  30. private String code;
  31. /**
  32. * 邮政编码
  33. */
  34. private String zip;
  35. /**
  36. * 拼音
  37. */
  38. private String spell;
  39. /**
  40. * 拼音首字母
  41. */
  42. private String spellFirst;
  43. /**
  44. * 地址全名
  45. */
  46. private String fullName;
  47. /**
  48. * 地址全名拼音首字母
  49. */
  50. private String fullInitials;
  51. /**
  52. * 排序
  53. */
  54. private Integer orderNumber;
  55. }

PositionMapper.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.wkf.workrecord.dao.PositionMapper">
  4. </mapper>

PositionUtils.java:

  1. public class PositionUtils {
  2. public final static String URL_HEAD = "https://xingzhengquhua.bmcx.com/";
  3. public final static String URL_TAIL = "__xingzhengquhua/";
  4. public static List<PositionEntity> reqPosition(String url) throws InterruptedException {
  5. String htmlStr = HttpUtils.getRequest(url);
  6. //解析字符串为Document对象
  7. Document doc = Jsoup.parse(htmlStr);
  8. //获取body元素,获取class="fc"的table元素
  9. Elements table = doc.body().getElementsByAttributeValue("bgcolor", "#C5D5C5");
  10. //获取tbody元素
  11. Elements children;
  12. children = table.first().children();
  13. //获取tr元素集合
  14. Elements tr = children.get(0).getElementsByTag("tr");
  15. List<PositionEntity> result = new ArrayList<>();
  16. //遍历tr元素,获取td元素,并打印
  17. for (int i = 3; i < tr.size(); i++) {
  18. Element e1 = tr.get(i);
  19. Elements td = e1.getElementsByTag("td");
  20. if (td.size() < 2) {
  21. break;
  22. }
  23. String name = td.get(0).getElementsByTag("td").first().getElementsByTag("a").text();
  24. String code = td.get(1).getElementsByTag("td").first().getElementsByTag("a").text();
  25. if (CheckUtils.isEmpty(name) || CheckUtils.isEmpty(code)) {
  26. continue;
  27. }
  28. result.add(new PositionEntity(name, Long.parseLong(code)));
  29. }
  30. //防止ip被封
  31. Thread.sleep(10000);
  32. return result;
  33. }
  34. }

PinyinUtils.java:

  1. public class PinyinUtils {
  2. private final static HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
  3. static {
  4. format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
  5. format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
  6. format.setVCharType(HanyuPinyinVCharType.WITH_V);
  7. }
  8. /**
  9. * 字符串转拼音
  10. *
  11. * @param str
  12. * 中文字符串
  13. * @param fill
  14. * 分隔符
  15. * @return 返回中文的拼音串
  16. */
  17. public static String str2Pinyin(String str, String fill) {
  18. if (null == str) {
  19. return null;
  20. }
  21. try {
  22. StringBuilder sb = new StringBuilder();
  23. if (fill == null)
  24. fill = "";
  25. boolean isCn = true;
  26. for (int i = 0; i < str.length(); i++) {
  27. char c = str.charAt(i);
  28. if (i > 0 && isCn) {
  29. sb.append(fill);
  30. }
  31. if (c == ' ') {
  32. sb.append(fill);
  33. }
  34. // 1、判断c是不是中文
  35. if (c >= 'u4e00' && c <= 'u9fa5') {
  36. isCn = true;
  37. String[] piyins = PinyinHelper.toHanyuPinyinStringArray(c, format);
  38. if (null == piyins || 0 >= piyins.length) {
  39. continue;
  40. }
  41. sb.append(piyins[0]);
  42. } else {
  43. // 不是中文
  44. if (c >= 'A' && c <= 'Z') {
  45. sb.append((char)(c + 32));
  46. } else {
  47. sb.append(c);
  48. }
  49. isCn = false;
  50. }
  51. }
  52. return sb.toString();
  53. } catch (BadHanyuPinyinOutputFormatCombination e) {
  54. e.printStackTrace();
  55. }
  56. return null;
  57. }
  58. /**
  59. * 拼音首字母
  60. *
  61. * @param str
  62. * 中文字符串
  63. * @return 中文字符串的拼音首字母
  64. */
  65. public static String strFirst2Pinyin(String str) {
  66. if (null == str) {
  67. return null;
  68. }
  69. try {
  70. StringBuilder sb = new StringBuilder();
  71. for (int i = 0; i < str.length(); i++) {
  72. char c = str.charAt(i);
  73. // 1、判断c是不是中文
  74. if (c >= 'u4e00' && c <= 'u9fa5') {
  75. String[] piyins = PinyinHelper.toHanyuPinyinStringArray(c, format);
  76. if (null == piyins || 0 >= piyins.length) {
  77. continue;
  78. }
  79. sb.append(piyins[0].charAt(0));
  80. } else {
  81. // 不是中文
  82. if (c >= 'A' && c <= 'Z') {
  83. sb.append((char)(c + 32));
  84. } else {
  85. sb.append(c);
  86. }
  87. }
  88. }
  89. return sb.toString();
  90. } catch (BadHanyuPinyinOutputFormatCombination e) {
  91. e.printStackTrace();
  92. }
  93. return null;
  94. }
  95. }

以上就是Java怎么解析html中的内容并存到数据库的详细内容,更多关于Java怎么解析html中的内容并存到数据库的资料请关注九品源码其它相关文章!