CyberNeko HTML Parser関係Tips
サンプルソースコード
特定URLのHTMLの内容をDOMで取り出してAuto-Discovery URLを取得するイメージで。
package sample.parser; import java.io.IOException; import java.io.InputStream; import java.net.URL; import javax.xml.transform.TransformerException; import org.cyberneko.html.parsers.DOMParser; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import com.sun.org.apache.xpath.internal.XPathAPI; public class DOMParserSample { public Document parse(InputStream in) throws SAXException, IOException { DOMParser parser = new DOMParser(); parser.setFeature("http://xml.org/sax/features/namespaces", false); parser.setFeature("http://cyberneko.org/html/features/scanner/notify-builtin-refs", true); // parser.setFeature("http://cyberneko.org/html/features/scanner/ignore-specified-charset", true); // parser.setProperty("http://cyberneko.org/html/properties/default-encoding", encoding); parser.parse(new InputSource(in)); Document document = parser.getDocument(); return document; } public static void main(String[] args) { String url = "http://d.hatena.ne.jp/terazzo/"; Document document = null; InputStream in = null; DOMParserSample sample = new DOMParserSample(); try { in = new URL(url).openStream(); document = sample.parse(in); // RSS 1.0用のAuto-Discovery URLを取得する Node rssNode = XPathAPI.selectSingleNode(document.getDocumentElement(), "//LINK[@rel='alternate'][@type='application/rss+xml'][@title='RSS']/@href"); if (rssNode != null) { System.err.println("Auto-discovered URL = " + rssNode.getNodeValue()); } } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
こんなときは……
- XPathで要素が見つからない
- 要素名を大文字にする
- Document#getDocumentElement()やXPathAPI#selectNodeList()などでHIERARCHY_REQUEST_ERRが出る
- parser.setFeature("http://xml.org/sax/features/namespaces", false);を付ける
- 「nbsp」が「?」に文字化け
- parser.setFeature("http://cyberneko.org/html/features/scanner/notify-builtin-refs", true);を付ける
- さらにEntityReference(nodeTypeがNode.ENTITY_REFERENCE_NODE)として取得できるので内容をgetNodeName()などで取り出す
- 「〜」が「?」に文字化け
- HTMLがShift_JISなら以下を試してみる
parser.setFeature("http://cyberneko.org/html/features/scanner/ignore-specified-charset", true);
parser.setProperty("http://cyberneko.org/html/properties/default-encoding", "Windows-31J");