簡體   English   中英

Java:我有一個很大的html字符串,需要提取href =“…”文本

[英]Java: I have a big string of html and need to extract the href=“…” text

我有一個包含很大一部分html的字符串,並且正在嘗試從字符串的href =“ ...”部分提取鏈接。 href可以采用以下形式之一:

<a href="..." />
<a class="..." href="..." />

我確實沒有正則表達式的問題,但是由於某些原因,當我使用以下代碼時:

        String innerHTML = getHTML(); 
  Pattern p = Pattern.compile("href=\"(.*)\"", Pattern.DOTALL);
  Matcher m = p.matcher(innerHTML);
  if (m.find()) {
   // Get all groups for this match
   for (int i=0; i<=m.groupCount(); i++) {
    String groupStr = m.group(i);
    System.out.println(groupStr);

   }
  }

有人可以告訴我我的代碼有什么問題嗎? 我在php中做過這些事情,但是在Java中我卻以某種方式做錯了什么。正在發生的事情是,每當我嘗試打印它時,它都會打印整個html字符串...

編輯:以便每個人都知道我正在處理哪種字符串:

<a class="Wrap" href="item.php?id=43241"><input type="button">
    <span class="chevron"></span>
  </a>
  <div class="menu"></div>

每次我運行代碼時,它都會打印整個字符串...這就是問題所在...

關於使用jTidy ...我正在研究它,但是知道在這種情況下出了什么問題也很有趣...

.* 

這是一個貪婪的操作,它將使用包括引號在內的任何字符。

嘗試類似:

"href=\"([^\"]*)\""

您發布的代碼有兩個問題:

首先,您的正則表達式中的.*是貪婪的。 這將使其匹配所有字符,直到找到最后一個"字符為止。您可以通過將其更改為.*?來使此匹配不貪心。

其次,要獲取所有匹配項,您需要使用Matcher.find進行迭代,而不是查找組。 組使您可以訪問正則表達式的每個括號部分。 但是,您每次都在尋找整個正則表達式匹配時。

將它們放在一起將為您提供以下代碼,這些代碼應該可以滿足您的需求:

Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.DOTALL);
Matcher m = p.matcher(innerHTML);

while (m.find()) 
{
    System.out.println(m.group(1));
}

正則表達式非常有用,但不適用於此特定目的。 通常,您要為此使用基於堆棧的解析器。 看一下Java HTML解析器API的jTidy

使用內置的解析器。 就像是:

    EditorKit kit = new HTMLEditorKit();
    HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument();
    doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
    kit.read(reader, doc, 0);

    HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);

    while (it.isValid())
    {
        SimpleAttributeSet s = (SimpleAttributeSet)it.getAttributes();
        String href = (String)s.getAttribute(HTML.Attribute.HREF);
        System.out.println( href );
        it.next();
    }

或使用ParserCallback:

import java.io.*;
import java.net.*;
import javax.swing.text.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;

public class ParserCallbackText extends HTMLEditorKit.ParserCallback
{
    public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos)
    {
        if (tag.equals(HTML.Tag.A))
        {
            String href = (String)a.getAttribute(HTML.Attribute.HREF);
            System.out.println(href);
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        Reader reader = getReader(args[0]);
        ParserCallbackText parser = new ParserCallbackText();
        new ParserDelegator().parse(reader, parser, true);
    }

    static Reader getReader(String uri)
        throws IOException
    {
        // Retrieve from Internet.
        if (uri.startsWith("http:"))
        {
            URLConnection conn = new URL(uri).openConnection();
            return new InputStreamReader(conn.getInputStream());
        }
        // Retrieve from file.
        else
        {
            return new FileReader(uri);
        }
    }
}

Reader可以是StringReader。

另一種簡單可靠的方法是使用Jsoup

Document doc = Jsoup.connect("http://example.com/").get();
Elements links = doc.select("a[href]");
for (Element link : links){
  System.out.println(link.attr("abs:href"));
}

您可以使用html解析器庫。 例如, jtidy為您提供了html的DOM模型,從中您可以提取所有“ a”元素並讀取其“ href”屬性

"href=\\"(.*?)\\""也應該起作用,但是我認為Kugel的答案會更快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM