【问题标题】:How can I store data, using Jsoup如何使用 Jsoup 存储数据
【发布时间】:2023-03-04 10:33:01
【问题描述】:

我的问题如下:我从一个网站用 Jsoup 获得了一些数据(Jsoup 代码也来自这里)

    public class Kereso {

   public static void main(String[] args) throws IOException {
      String html = "http://www.szerencsejatek.hu/xls/otos.html";

      Document doc = Jsoup.connect(html).get();


       Elements tableElements = doc.select("table");

       Elements tableRowElements = tableElements.select(":not(thead) tr");
       for (Element row : tableRowElements) {

           Elements rowItems = row.select("td");
           for (Element rowItem : rowItems) {
               System.out.println(rowItem.text());
           }
           System.out.println();
       }
   }
}

我从网站上得到的每一行都应该是一个对象,我想将所有这些对象存储在一个 ArrayList 中

这是对象的类,以及它们需要的数据:

public class Huzas {

    private String ev;
    private String het;
    private String huzasdatum;
    private String otosDb;
    private String otos;
    private String negyesDb;
    private String negyes;
    private String harmasDb;
    private String harmas;
    private String kettesDb;
    private String kettes;
    private int szam1;
    private int szam2;
    private int szam3;
    private int szam4;
    private int szam5;

    public Huzas(String ev, String het, String huzasdatum, String otosDb, String otos, String negyesDb, String negyes, String harmasDb, String harmas, String kettesDb, String kettes, int szam1, int szam2, int szam3, int szam4, int szam5) {
        this.ev = ev;
        this.het = het;
        this.huzasdatum = huzasdatum;
        this.otosDb = otosDb;
        this.otos = otos;
        this.negyesDb = negyesDb;
        this.negyes = negyes;
        this.harmasDb = harmasDb;
        this.harmas = harmas;
        this.kettesDb = kettesDb;
        this.kettes = kettes;
        this.szam1 = szam1;
        this.szam2 = szam2;
        this.szam3 = szam3;
        this.szam4 = szam4;
        this.szam5 = szam5;
    }

是否可以以这种方式存储它们?如果是,当然如何?

【问题讨论】:

  • 网站上每一列的顺序是否固定?还是列的顺序会改变?
  • 我强烈建议在这里使用构建器模式,至少使用强类型方法。

标签: java arraylist jsoup store


【解决方案1】:

我从网站获得的每一行都应该是一个对象,我想将所有这些对象存储在一个 ArrayList 中。

要将列数据与您的Huzas 对象链接,您必须编写一个包装器。

如果我没记错的话,您正在遍历某个站点上的表,因此您应该已经对列的顺序有所了解。只需在迭代中捕获每个列的值,并在遇到 Huzas 对象时设置它的值。

但首先我们需要一些列表,我们可以在其中将列与每次 DOM 迭代获得的值进行映射。

// The elements should be in order of the columns in the DOM
String[] columnsFromDOM = {"ev", "huzasdatum", "het" ..... } 

现在

List<Huzas> listOfHuzas = new ArrayList<>();
for (Element row : tableRowElements) {

       Map<String, String> columnToObjectMap = new HashMap<>();
       Elements rowItems = row.select("td");
       int index = 0;
       for (Element rowItem : rowItems) {
           // (key,value) => ("ev", value_from_dom )
           columnToObjectMap.put(columnsFromDOM[index], rowItem.text());
           indexx++;
       }

       // now columnToObjectMap contains your values along with the relavant keys
       // So now catch each value and assign it to a Huzas object

       String ev = columnToObjectMap.get("ev");
       String kettes = columnToObjectMap.get("kettes");
       ......

       Huzas huzas = new Huzas(ev, het, .....);
       listofHuzas.add(huzas);
   }

【讨论】:

  • 在这一行中:columnsFromDOM, rowItem.text()); IDE 说:不兼容的类型:String[] 不能转换为 String 其他部分,工作正常。
  • 哦,是的,完全正确。一个小打字机。更新答案。它应该是 columnsFromDOM[index] 而不是 columnsFromDOM
【解决方案2】:

由于该站点具有简单且结构化的 html,因此您可以简单地这样做

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Kereso {

    public static void main(String[] args) throws IOException {
        String html = "http://www.szerencsejatek.hu/xls/otos.html";
        List<Huzas> listOfHuzas = new ArrayList<Huzas>();

        Document doc = Jsoup.connect(html).get();
        Elements rows = doc.select("tr");
        rows.remove(0); //Remove head row
        for (Element row : rows) {
            Elements children = row.children();
            listOfHuzas.add(new Huzas(children.get(0).text(), // ev
                            children.get(1).text(), // het
                            children.get(2).text(), // huzasdatum
                            children.get(3).text(), // otosDb
                            children.get(4).text(), // otos
                            children.get(5).text(), // negyesDb
                            children.get(6).text(), // negyes
                            children.get(7).text(), // harmasDb
                            children.get(8).text(), // harmas
                            children.get(9).text(), // kettesDb
                            children.get(10).text(), // kettes
                            Integer.parseInt(children.get(11).text()), // szam1
                            Integer.parseInt(children.get(12).text()), // szam2
                            Integer.parseInt(children.get(13).text()), // szam3
                            Integer.parseInt(children.get(14).text()), // szam4
                            Integer.parseInt(children.get(15).text())) // szam5
                        );
        }
        System.out.println(listOfHuzas);
    }
}

因为每一行正好有 16 列,并且所有 int 字段都有值,所以为了简单起见,我只是直接索引子元素。您可以在此处添加更多长度检查或错误处理。

【讨论】:

  • 这里我只获取元素的哈希码。如何获取对象的数据/内容?
  • 哦,没关系。我认为覆盖 toString() 可以解决这个问题。
  • 两个答案都可以正常工作,但是这样,代码更具可读性,并且更容易实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 2021-07-19
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
相关资源
最近更新 更多