2011-10-09 198 views
19

我正在使用JSoup解析來自http://www.latijnengrieks.com/vertaling.php?id=5368的內容。這是第三方網站,並未指定正確的編碼。我用下面的代碼加載數據:JSoup字符編碼問題

public class Loader { 

    public static void main(String[] args){ 
     String url = "http://www.latijnengrieks.com/vertaling.php?id=5368"; 

     Document doc; 
     try { 

      doc = Jsoup.connect(url).timeout(5000).get(); 
      Element content = doc.select("div.kader").first(); 
      Element contenttableElement = content.getElementsByClass("kopje").first().parent().parent(); 

      String contenttext = content.html(); 
      String tabletext = contenttableElement.html(); 

      contenttext = Jsoup.parse(contenttext).text(); 
      contenttext = contenttext.replace("br2n", "\n"); 
      tabletext = Jsoup.parse(tabletext.replaceAll("(?i)<br[^>]*>", "br2n")).text(); 
      tabletext = tabletext.replace("br2n", "\n"); 

      String text = contenttext.substring(tabletext.length(), contenttext.length()); 
      System.out.println(text); 


     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


    }  

} 

此給出以下的輸出:

Aeneas dwaalt rond in Troje en zoekt Cre?sa. Cre?sa is echter op de vlucht gestorven Plotseling verschijnt er een schim. Het is de schim van Cre?sa. De schim zegt:'De oorlog woedt!' Troje is ingenomen! Cre?sa is gestorven:'Vlucht!' Aeneas vlucht echter niet. Dan spreekt de schim:'Vlucht! Er staat jou een nieuw vaderland en een nieuw koninkrijk te wachten.' Dan pas gehoorzaamt Aeneas en vlucht. 

有什麼辦法了?標記可以是輸出中的原始(ü)?

+0

Jsoup可分析的東西。你如何可視化輸出?在控制檯窗口中?寫入文件的文本? –

+0

最終輸出將是在Android TextView的,但是這是一個控制檯窗口,而Android的logcat給出了相同的結果。 – Hihaatje

+0

Balus有你的答案。 –

回答

47

charset屬性在HTTP響應Content-Type標頭中缺失。解析HTML時,Jsoup將採用平臺默認字符集。 Document.OutputSettings#charset()不適用於僅用於演示文稿(位於html()text()),不用於解析數據(換句話說,已經太晚了)。

您需要讀取URL爲InputStream並手動指定方法中的字符集。

String url = "http://www.latijnengrieks.com/vertaling.php?id=5368"; 
Document document = Jsoup.parse(new URL(url).openStream(), "ISO-8859-1", url); 
Element paragraph = document.select("div.kader p").first(); 

for (Node node : paragraph.childNodes()) { 
    if (node instanceof TextNode) { 
     System.out.println(((TextNode) node).text().trim()); 
    } 
} 

這將導致這裏

Aeneas dwaalt rond in Troje en zoekt Creüsa. 
Creüsa is echter op de vlucht gestorven 
Plotseling verschijnt er een schim. 
Het is de schim van Creüsa. 
De schim zegt:'De oorlog woedt!' 
Troje is ingenomen! 
Creüsa is gestorven:'Vlucht!' 
Aeneas vlucht echter niet. 
Dan spreekt de schim:'Vlucht! Er staat jou een nieuw vaderland en een nieuw koninkrijk te wachten.' 
Dan pas gehoorzaamt Aeneas en vlucht. 
+0

**這是**我正在尋找的答案!再次感謝Balus,如果可以的話,還有5+! –

+0

@Hovercraft:不客氣。順便說一句,喬納森增加了'元素#textNodes()'爲即將到來的Jsoup 1.6.2哪些不應該做'instanceof'檢查是多餘的。你可以'for(TextNode node:paragraph.textNodes())'。另請參見http://stackoverflow.com/questions/7164376/how-to-extract-separate-text-nodes-with-jsoup/7164518#7164518 – BalusC

+0

感謝這個答案。 – AHungerArtist

4

Jsoup文檔指出Jsoup在閱讀文檔時應該自動檢測正確的字符集,但由於某種原因,它不適合我。然後,我嘗試手動設置使用outputSettings()字符集(...)的文件的字符集:

doc.outputSettings().charset("ISO-8859-1"); 

但仍然沒有工作,所以也許我做錯了(我剛學Jsoup)。

一說沒有工作變通辦法,至少對我來說,是使用掃描儀,有它的字符集設置在網頁閱讀:

 String charset = "ISO-8859-1"; 

    URL myUrl = new URL(url); 
    Scanner urlScanner = new Scanner(myUrl.openStream(), charset); 
    StringBuilder sb = new StringBuilder(); 
    while (urlScanner.hasNextLine()) { 
     sb.append(urlScanner.nextLine() + "\n"); 
    } 
    urlScanner.close(); 

    doc = Jsoup.parse(sb.toString()); 

但我會是繼此線程看如果有人提出更好的建議,那麼不需要使用另一個類來讀取HTML。

+1

就我而言,我使用UTF-8作爲中文文本!無論如何,謝謝! – Phuong

10

好吧,我想通了另一種方式來做到這一點。在我的情況下,我有一個Jsoup Connection對象,並且我想從一個使用「ISO-8859」編碼的網站中的post()請求中檢索html響應。由於JSOUP的默認編碼是UTF-8,所以來自響應(html)的內容隨着 替換一些字母而來。我需要以某種方式將其轉換爲ISO-8859-15。爲了執行該操作,我創建了連接

Connection connectionTest = Jsoup.connect("URL") 
.cookie("cookiereference", "cookievalue") 
.method(Method.POST); 

之後,我創建了一個包含帖子答案的響應文檔。由於不清楚我們如何在Jsoup中設置響應的編碼,我選擇執行後,然後將響應保存爲字節,保留編碼屬性。之後,我創建了一個傳遞這個Byte數組的新字符串和必須應用的正確編碼。之後,文檔將使用正確的編碼創建。

Document response = Jsoup.parse(new String(
connectionTest.execute().bodyAsBytes(),"ISO-8859-15")); 

因此,有前和修改後的回報,當我們使用response.html()

前:

62。00年9月1日 - 技術支持,維護等服務,在信息技術

後:

62.09-1-00 - 技術支持,維修等服務信息技術

-1

我用:

public static String charset = "UTF-8"; 
doc = Jsoup.parse(new URL(theURL).openStream(), charset, theURL); 

同時,該類正確保存的UTF-8