|
|
| << Kaz Muzik Blog Google Search Project #5 | Kaz Muzik Blog Backup Project #28 - Kaz Muzik Blog Google Search Project #6 >> |
Kaz Muzik Blog Backup Project #27 - LiveJournalMonthlyParser & LivrJournalMonthlyManager - KazMuzik Blog
2007-11-11 10:47
以前の方法では、このブログのバックアップがとれなくなったため、新しい方法が必要になりました。ヒントは Google Search にありました。うざいと思っていた calendar の月の summary page を、逆に利用してしまう方法です。このブログは、去年の 9月から始めたので、それからの月ごとのページをすべて fetch してくれば、エントリの内容まではわかりませんが、ID やタイトル、時刻の一覧表は作成できます。以前の方法では、エントリの数が多くなると、例え可能だったとしても、"/?skip=NNN" で何回アクセスすればいいかわかりませんでしたが、このアイデアによる方法では、月の数だけアクセスすれば、必ず、すべての ID が取得できます。今月だったら、(2007 - 2006) x 12 + (11 - 9) + 1 = 15回です。
まずは、月の summary page を parse するクラスです。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Calendar;
import java.util.Date;
public class LiveJournalMonthlyParser extends BufferedReader {
private int yyyy;
private int mm;
private int dd;
public LiveJournalMonthlyParser(Reader in) throws IOException {
super(in);
}
public void close() throws IOException {
super.close();
}
public LiveJournalEntry parse() throws IOException {
int mode = 0;
while (true) {
String line = readLine();
if (line == null) {
break;
}
if (mode == 1) {
int n = line.indexOf(".livejournal.com/");
yyyy = Integer.parseInt( line.substring(n+17, n+21) );
mm = Integer.parseInt( line.substring(n+22, n+24) );
dd = Integer.parseInt( line.substring(n+25, n+27) );
mode = 0;
continue;
}
if (mode == 2) {
int n = line.indexOf(':');
int _hh = Integer.parseInt( line.substring(n-2,n) );
int _mm = Integer.parseInt( line.substring(n+1,n+3) );
if (line.charAt(n+4) == 'p') {
_hh += 12;
}
Calendar cal = Calendar.getInstance();
cal.set(yyyy, mm-1, dd, _hh, _mm);
Date date = cal.getTime();
n = line.indexOf(".livejournal.com/");
int m = line.indexOf('.', n+17);
int id = Integer.parseInt( line.substring(n+17,m) );
n = line.indexOf("</a>", m+7);
String title = line.substring(m+7,n);
LiveJournalEntry entry = new LiveJournalEntry(id);
entry.setTitle(title);
entry.setDate(date);
return entry;
}
if (line.indexOf("class=\"entryDate\"") >= 0) {
mode = 1;
continue;
}
if (line.indexOf("class=\"entry\"") >= 0) {
mode = 2;
continue;
}
}
return null;
}
} |
次は、これを利用して、月ごとに entry を管理するクラスです。
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
public class LiveJournalMonthlyManager {
public LiveJournalMonthlyManager() {
}
public List getEntries(int yyyy, int mm)
throws IOException {
String urlString = getURLString(yyyy, mm);
URL url = new URL( getURLString(yyyy, mm) );
InputStream is = null;
try {
is = url.openStream();
}
catch (Exception e) {
System.err.printf("! %s : %s%n", urlString, e.getMessage());
return null;
}
if (is == null) {
return null;
}
LiveJournalMonthlyParser parser
= new LiveJournalMonthlyParser(new InputStreamReader(is, "UTF-8"));
List list = new ArrayList();
while (true) {
LiveJournalEntry entry = parser.parse();
if (entry == null) {
break;
}
list.add(entry);
}
parser.close();
return list;
}
private static String getURLString(int yyyy, int mm) {
Formatter f = new Formatter();
f.format("http://kazuomik.livejournal.com/%04d/%02d/", yyyy, mm);
return f.toString();
}
public static void main(String[] args) throws Exception {
LiveJournalMonthlyManager manager = new LiveJournalMonthlyManager();
int yyyy = 2006;
int mm = 9;
while (true) {
List list = manager.getEntries(yyyy, mm);
if (list == null || list.size() < 1) {
break;
}
for (LiveJournalEntry entry : list) {
Date time = entry.getDate();
System.out.printf("%tF %tR\t%d\t%s%n",
time, time, entry.getId(), entry.getTitle());
}
if (++mm > 12) {
yyyy++;
mm -= 12;
}
}
}
} |
main() メソッドで、すべてのエントリの時刻、ID、タイトルをプリントします。次(#28)は、これを実行します。Tags: programming
|
|
|
|
|
|