【问题标题】:How to fetch data of multiple HTML tables through Web Scraping in Java如何通过 Java 中的 Web Scraping 获取多个 HTML 表的数据
【发布时间】:2016-04-21 11:34:17
【问题描述】:

我试图抓取网站的数据,在某种程度上我成功地实现了我的目标。但是,有一个问题是我试图抓取的网页中有多个 HTML 表格。现在,当我执行我的程序时,它只检索 CSV 文件中第一个表的数据,而不检索其他表。我的java类代码如下。

   public static void parsingHTML() throws Exception {
        //tbodyElements = doc.getElementsByTag("tbody");
        for (int i = 1; i <= 1; i++) {

            Elements table = doc.getElementsByTag("table");

            if (table.isEmpty()) {
                throw new Exception("Table is not found");
            }

            elements = table.get(0).getElementsByTag("tr");

            for (Element trElement : elements) {
                trElement2 = trElement.getElementsByTag("tr");
                tdElements = trElement.getElementsByTag("td");
                File fold = new File("C:\\convertedCSV9.csv");
                fold.delete();
                File fnew = new File("C:\\convertedCSV9.csv");
                FileWriter sb = new FileWriter(fnew, true);
                //StringBuilder sb = new StringBuilder(" ");
                //String y = "<tr>";

                for (Iterator<Element> it = tdElements.iterator(); it.hasNext();) {

                    //Element tdElement1 = it.next();
                    //final String content2 = tdElement1.text();
                    if (it.hasNext()) {
                        sb.append("\r\n");

                    }
                    for (Iterator<Element> it2 = trElement2.iterator(); it.hasNext();) {
                        Element tdElement2 = it.next();
                        final String content = tdElement2.text();

                        //stringjoiner.add(content);
                        //sb.append(formatData(content));
                        if (it2.hasNext()) {

                            sb.append(formatData(content));
                            sb.append("   ,   ");

                        }
                        if (!it.hasNext()) {
                            String content1 = content.replaceAll(",$", " ");
                            sb.append(formatData(content1));
                            //it2.next();

                        }
                        
                    }

                    System.out.println(sb.toString());
                    sb.flush();
                    sb.close();

                }
                System.out.println(sampleList.add(tdElements));

            }
        }
    }

我分析的是有一个循环只检查 tr tds。因此,在第一个表格之后,HTML 页面上有一个样式表。可能是由于样式表循环中断。我认为这就是它进入下一张桌子的原因。

P.S:这是我要废弃的链接 http://www.mufap.com.pk/nav_returns_performance.php?tab=01

【问题讨论】:

  • 强制你只看一张桌子的循环怎么样? for (int i = 1; i &lt;= 1; i++) {
  • 当我将其增加到 'i
  • 因为您对要查看的表格进行了硬编码。 elements = table.get(0).getElementsByTag("tr"); 无论您循环多少次,您都只会查看集合中的第一个表。

标签: java html csv web-scraping


【解决方案1】:

您在代码开头所做的将不起作用:

// loop just once, why
for (int i = 1; i <= 1; i++) {
    Elements table = doc.getElementsByTag("table");

    if (table.isEmpty()) {
        throw new Exception("Table is not found");
    }
    elements = table.get(0).getElementsByTag("tr");

在这里您只循环一次,读取所有table 元素,然后为您找到的first 表处理所有tr 元素。因此,即使您循环不止一次,您也总是会处理第一个 table

您必须迭代所有 table 元素,例如

for(Element table : doc.getElementsByTag("table")) {
    for (Element trElement : table.getElementsByTag("tr")) {
        // process "td"s and so on
    }
}

编辑 由于您在使用上面的代码时遇到问题,这里有一个更详尽的示例。请注意,我使用 Jsoup 来读取和解析 HTML(您没有指定您使用的是什么)

Document doc = Jsoup
                 .connect("http://www.mufap.com.pk/nav_returns_performance.php?tab=01")
                 .get();

for (Element table : doc.getElementsByTag("table")) {
    for (Element trElement : table.getElementsByTag("tr")) {
        // skip header "tr"s and process only data "tr"s
        if (trElement.hasClass("tab-data1")) {

            StringJoiner tdj = new StringJoiner(",");
            for (Element tdElement : trElement.getElementsByTag("td")) {
                tdj.add(tdElement.text());
            }

            System.out.println(tdj);
        }
    }
}

这将连接并打印所有数据单元格(具有tab-data1 类的单元格)。不过,您仍然需要修改它以写入您的 CSV 文件。

注意:在我的测试中,这会处理 21 个tables、243 个trs 和 2634 个tds。

【讨论】:

  • 非常感谢您的回答先生。您的代码正在运行,但仍然存在一个问题,即它会从页面中跳过前 16 个表并带来其余的表。
  • @AhmedTalha 在我的回答中添加了另一个示例
猜你喜欢
  • 2019-06-08
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多