前回は接続、取得まで行いました。
今回は解析についてです。
HTML解析はカスタマイズが容易なHTMLEditorKit.Parserクラスを利用して自作します。
HTMLEditorKit.Parserクラス
このクラスはタグなどのデータを検知し、指定した処理を行えるものです。使い方は、HTMLファイルを読み込みながら解析を行うのでコールバッククラスを定義して指定した処理を行います。
主なメッソッド
handleStartTag(HTML.Tag t,
MutableAttributeSet a,
int pos)開始タグ検知時の処理をします。例:<title> ⇒titleタグを検知⇒処理handleEndTag(HTML.Tag t,
int pos)終了タグ検知時の処理をします。例:</titele>⇒titleタグを検知⇒処理handleText(char[] data,
int pos)通常文字列検知時の処理をします。例:<title>タイトル</title>あいうえお⇒「タイトル」及び「あいうえお」という文字列を検知⇒処理 handleSimpleTag(HTML.Tag t,
MutableAttributeSet a,
int pos)単独なタグ検知時の処理をします。
例:<br />⇒brタグを検知⇒処理
コールバック処理の例
<html> <head> <title>タイトル</title> </head> <body> あいうえお </body> </html>
titleタグ内の文字列を取得したい場合public class Htmlparsercallback extends HTMLEditorKit.ParserCallback {
boolean tagon = false;
public void handleStartTag(HTML.Tag tag,MutableAttributeSet attr, int pos){
if(tag.equals(HTML.Tag.TITLE)){
tagon = ture;
}
}
public void handleText(char[] data,int pos){
if(tagon){
System.out.println(data);
}
}
public void handleEndTag(HTML.Tag tag,int pos){
if(tag.equals(HTML.Tag.TITLE)){
tagon = false;
}
}
}
コールバック処理の呼び出し
BufferedReader bstr = new BufferedReader(new InputStreamReader(httpoc.getInputStream())); Htmlparsercallback htmlpc = new Htmlparsercallback(); ParserDelegator pd = new ParserDelegator(); pd.parse(bstr, htmlpc, true);
コールバック処理の呼び出しは以上です。あとは自己流にコードを書き換えればスクレイピングを実現できます。サンプルコードとしてTREE構造を考慮した簡易的なスクレイピングプログラムを載せておきます。かなりごり押しぎみですが・・・
サンプルコード
mainpublic class Analyzer {
public static void main(String args[]) {
try {
URL url = new URL(" ");
HttpURLConnection httpoc = (HttpURLConnection)url.openConnection();
httpoc.connect();
BufferedReader bstr = new BufferedReader(new InputStreamReader(httpoc.getInputStream()));
Htmlparsercallback htmlpc = new Htmlparsercallback();
ParserDelegator pd = new ParserDelegator();
pd.parse(bstr, htmlpc, true);
httpoc.disconnect();
System.out.println(SearchStr);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
callbackpublic class Htmlparsercallback extends HTMLEditorKit.ParserCallback {
//左から順に書き換えてください。
String[] htmltags = {"html", "head", "title"};
int maxhtmltags = 3;
/*---------------------------------------------------------------------*/
int j = 0;
List<Integer> slist = new ArrayList<Integer>(Arrays.asList(0));
List<Integer> klist = new ArrayList<Integer>(Arrays.asList(0));
List<String> ktags = new ArrayList<String>(Arrays.asList(""));
public void handleStartTag(HTML.Tag tag,MutableAttributeSet attr, int pos){
if(klist.get(j)>=1){
if(tag.toString().equals(htmltags[0])){
if(slist.get(0)!=0){
slist.add(1);
klist.add(0);
ktags.add("");
j++;
}
else if(slist.get(0)==0){
slist.set(0, 1);
}
}
else if(tag.toString().equals(ktags.get(j))){
klist.set(j, klist.get(j)+1);
}
}
else if(tag.toString().equals(htmltags[slist.get(j)])){
slist.set(j, slist.get(j)+1);
}
else if(slist.get(j)>=1){
klist.set(j, 1);
ktags.set(j,tag.toString());
}
}
public void handleText(char[] data,int pos){
if(slist.get(j)==maxhtmltags){
System.out.println(data);
}
}
public void handleEndTag(HTML.Tag tag,int pos){
if(tag.toString().equals(htmltags[0])){
if(j!=0){
slist.remove(j);
klist.remove(j);
ktags.remove(j);
j--;
}
else if(j==0){
slist.set(0, 0);
klist.set(0, 0);
}
}
else if(tag.toString().equals(ktags.get(j))){
klist.set(j, klist.get(j)-1);
}
else if(tag.toString().equals(htmltags[slist.get(j)-1])){
slist.set(j, slist.get(j)-1);
}
}
}