2011-08-13 56 views
0

我要提取d公司名稱,面值從 http://money.rediff.com/companies/20-microns-ltd/15110088如何提取使用jtidy和XPath

我注意到,這個任務可以使用XPath API來完成數據。 因爲這是一個html頁面,我正在使用jtidy解析器。

這是我必須提取的面值xpath。

/html/body/div[4]/div[6]/div[9]/div/table/tbody/tr[4]/td[2] 

這是我的代碼

URL oracle = new URL("http://money.rediff.com/companies/20-microns-ltd/15110088"); 
URLConnection yc = oracle.openConnection(); 
InputStream is = yc.getInputStream(); 
is = oracle.openStream(); 
Tidy tidy = new Tidy(); 
tidy.setQuiet(true); 
tidy.setShowWarnings(false); 
Document tidyDOM = tidy.parseDOM(is, null); 
XPathFactory xPathFactory = XPathFactory.newInstance(); 
XPath xPath = xPathFactory.newXPath(); 
String expression = "/html"; 
XPathExpression xPathExpression = xPath.compile(expression); 
Object result = xPathExpression.evaluate(tidyDOM,XPathConstants.NODESET); 
System.out.println(result.toString()); 

請進一步引導我,因爲,我無法找到上述

回答

3

一個正確的解決方案,儘量不要使用「全」的XPath。

//div[@id='leftcontainer']//div[9]//table//tr[4]/td[2] 

優於

/html/body/.../.../.../.../.../... 

大多數HTML網頁是無效的甚至是良好的。所以DOM結構在被「真實世界的HTML解析器」處理時可能會發生變化。例如,如果不存在<tbody>,則可以在<table>下插入<tbody>。當不同的HTML解析器生成不同的DOM樹時,事情會變得更糟,因此一個XPath對於一個解析器可能是有效的,而另一個則不適用。我寧願使用「通配符」,如table//tr[4]而不是table/tbody/tr[4]table/tr[4],這樣我就可以忘記<tbody>。這些表達式在用於混亂的真實世界HTML頁面時更加健壯。

您可以使用Firepath,Firebug的插件,然後是Firefox的插件來調試XPath表達式。

p.s.您可以嘗試我的JHQL(http://github.com/wks/jhql)項目來完成此任務。如果你有更多的頁面來提取數據,你會喜歡它。

+0

我會按照你的指導方針在這裏發佈結果。與此同時,你對給定的代碼有什麼建議? –

+0

您的代碼中的一些對象可以共享。編譯XPath非常昂貴。如果頁面應該被連續監視,那麼可以使XPath成爲一個靜態字段。 'Tidy'不是線程安全的(參見:[link](http://markmail.org/message/4uf4daiynx545s6i)),但HtmlCleaner聲稱是安全的(參見[link](http://htmlcleaner.sourceforge)。 net/javause.php))。然後一個線程安全的HTML解析器也可以共享。 – wks

+0

並嘗試Jaxen。根據我的經驗,它比Java附帶的XPath實現快得多。 – wks