HTMLの特定の部分を抽出する(とあるBLOGサイト)
戻る
::::::::::::::
extractor.sh
::::::::::::::
#!/bin/sh
if [ $# = 2 ] ; then
FROM=$1
TO=$2
else
echo "Usage: $0 [from] [to]"
exit -1
fi
for INDEX in `seq ${FROM} ${TO}`; do
java -cp . MyExtractor ${INDEX}
### sleep 3
done
::::::::::::::
ContentRetriever.java
::::::::::::::
/**
$Id: extractor.html,v 1.1 2009/06/22 16:12:09 kishi Exp kishi $
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class ContentRetriever {
/** 処理対象URLの文字列 */
private String targetURL;
private URL url;
private long elapsedTime;
private StringBuilder responseBody = null;
private String encoding = null;
private int responseCode = 0;
private List responseHeader = null;
public ContentRetriever( String targetURL, String encoding ) {
this.targetURL = targetURL;
this.encoding = encoding;
}
public void execute() throws Exception {
try {
url = new URL( targetURL );
long start;
long end;
start = System.currentTimeMillis();
//---------------------------------------------------------------
// コネクトして、HttpURLConnection の作成
//---------------------------------------------------------------
HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
//---------------------------------------------------------------
// ユーザ・エージェントの設定
//---------------------------------------------------------------
String userAgent = RagUtil.sha1Digest( new Date().toString() + "128-256-384-512-640-768" );
if ( ( url.hashCode() + userAgent.hashCode() ) % 2 == 0 ) {
userAgent = userAgent.toUpperCase();
}
connection.setRequestProperty( "User-Agent", userAgent );
System.err.println( "User-Agent: " + userAgent );
//---------------------------------------------------------------
// キャッシュを使わない
//---------------------------------------------------------------
connection.setUseCaches( false );
//---------------------------------------------------------------
// リダイレクトに対して追従しない設定だが、追従してしまうの使用しない
// connection.setFollowRedirects( false);
// connection.setInstanceFollowRedirects( false);
//---------------------------------------------------------------
//---------------------------------------------------------------
// リクエストメソッドを明示的に指定
//---------------------------------------------------------------
connection.setRequestMethod( "GET" );
//---------------------------------------------------------------
// HTTP応答コードの取得
//---------------------------------------------------------------
responseCode = connection.getResponseCode();
// System.out.println( "コンテントレングスは " + connection.getContentLength() + " です。" );
//---------------------------------------------------------------
// レスポンスヘッダの取得
//---------------------------------------------------------------
ResponseHeaderObtainer obtainer = new ResponseHeaderObtainer( connection );
responseHeader = obtainer.getHeaders();
//---------------------------------------------------------------
// レスポンスボディの取得
//---------------------------------------------------------------
BufferedReader br = new BufferedReader( new InputStreamReader(
connection.getInputStream(), encoding ) );
String line;
responseBody = new StringBuilder();
while ( ( line = br.readLine() ) != null ) {
responseBody.append( line + "\n" );
}
br.close();
//---------------------------------------------------------------
// ディスコネクトする
//---------------------------------------------------------------
connection.disconnect();
end = System.currentTimeMillis();
elapsedTime = ( end - start ) ;
} catch ( Exception exception ) {
throw exception;
}
}
public int getResponseCode() {
return responseCode;
}
public List getResponseHeader() {
return responseHeader;
}
public String getResponseBody() {
return responseBody.toString();
}
public long getElapsedTime() {
return elapsedTime;
}
/** メインメソッド */
public static void main( String args[] ) throws Exception {
if ( args.length != 3 ) {
System.out.println( "Usage: java ContentRetriever [url] [conntectTimeOut] [readTimeOut]" );
System.exit( 1 );
}
/******************************************************************************/
/* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
/******************************************************************************/
System.setProperty ( "sun.net.client.defaultConnectTimeout", args[ 1 ] );
/**********************************************************************************/
/* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
/**********************************************************************************/
System.setProperty ( "sun.net.client.defaultReadTimeout", args[ 2 ] );
try {
ContentRetriever retriever = new ContentRetriever( args[ 0 ], "UTF8" );
retriever.execute();
System.out.println( retriever.getResponseBody() );
System.out.printf( "所要時間: " + retriever.getElapsedTime() + " msec" );
} catch ( Exception e ) {
throw e;
}
}
}
::::::::::::::
MyExtractor.java
::::::::::::::
/**
* $Id: extractor.html,v 1.1 2009/06/22 16:12:09 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
public class MyExtractor {
public static SummaryInfo getSummaryInfo( String responseBody ) {
SummaryInfo info = new SummaryInfo();
Pattern p;
Matcher m;
//-----------------------------------------------
// 総ブログ数の取り出し
//-----------------------------------------------
p = Pattern.compile( "<span class=\"blog_count\">(.*?)<\\/span>",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
m = p.matcher( responseBody );
if ( m.find() ) {
// System.out.println( m.group( 1 ) );
info.setBlogCount( new Long( m.group( 1 ) ).longValue() );
}
//-----------------------------------------------
// 総アクセス数の取り出し
//-----------------------------------------------
p = Pattern.compile( "総アクセス数:<span class=\"menu_accesscount\">(.*?)<\\/span>件",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
m = p.matcher( responseBody );
if ( m.find() ) {
// System.out.println( m.group( 1 ) );
info.setAccessCount( new Long( m.group( 1 ) ).longValue() );
}
//-----------------------------------------------
// タイトルの取り出し
//-----------------------------------------------
p = Pattern.compile( "<title>(.*?)<\\/title>?",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL );
m = p.matcher( responseBody );
if ( m.find() ) {
// System.out.println( m.group( 1 ) );
info.setTitle( m.group( 1 ) );
}
return info;
}
/**
* 単体テスト用
*/
public static void main( String[] args ) throws Exception {
if ( args.length != 1 ) {
System.err.println( "Usage: java -cp . MyExtractor [index]" );
System.exit( -1 );
}
/******************************************************************************/
/* 接続タイムアウトの設定; 設定された時間でコネクトできない場合はタイムアウト */
/******************************************************************************/
System.setProperty ( "sun.net.client.defaultConnectTimeout", "10000" );
/**********************************************************************************/
/* 読み取りタイムアウトの設定; 設定された時間で読み取りできない場合はタイムアウト */
/**********************************************************************************/
System.setProperty ( "sun.net.client.defaultReadTimeout", "10000" );
String index = args[ 0 ];
String urlString = "http://www.doblog.com/weblog/myblog/" + index;
try {
ContentRetriever retriever = new ContentRetriever( urlString , "UTF8" );
retriever.execute();
String responseBody = retriever.getResponseBody();
System.err.printf( "インデックス: %7s\t" , index );
System.err.print( "応答コード: " + retriever.getResponseCode() + "\t" );
System.err.print( "所要時間: " + retriever.getElapsedTime() + " msec\n" );
// 統計情報を取得
SummaryInfo info = MyExtractor.getSummaryInfo( responseBody );
// 総アクセス数を総ブログ数で除算したものをポイントにする
double point = info.getBlogCount() == 0 ? 0.0 : info.getAccessCount() * 1.0 / info.getBlogCount();
System.out.printf( "ポイント: %10.1f\t総ブログ数: %7d\t総アクセス数: %7d\tタイトル: %s\tURL: %s\n",
point,
info.getBlogCount(),
info.getAccessCount(),
info.getTitle() ,
urlString );
} catch ( Exception e ) {
throw e;
}
}
}
::::::::::::::
RagUtil.java
::::::::::::::
/**
* $Id: extractor.html,v 1.1 2009/06/22 16:12:09 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.security.MessageDigest;
public class RagUtil {
/** 文字列からSHA1ハッシュ値を求めて16進で表示する
@param str 入力文字列
@return ハッシュ値
*/
static public String sha1Digest( String str ) {
StringBuffer result = new StringBuffer( "" );
try {
MessageDigest md = MessageDigest.getInstance( "SHA1" ); /* MD5のときは"MD5"とすればいいですよ! */
md.update( str.getBytes() );
byte[] digest = md.digest();
for ( int i = 0; i < digest.length; i++ ) {
if ( ( digest[ i ] & 0x0ff ) / 16 == 0 ) {
result.append( "0" );
}
result.append( Integer.toHexString( digest[ i ] & 0x0ff ) );
}
} catch ( Exception e ) {}
return result.toString();
}
}
::::::::::::::
ResponseHeaderObtainer.java
::::::::::::::
import java.net.*;
import java.io.*;
import java.util.*;
/**
$Id: extractor.html,v 1.1 2009/06/22 16:12:09 kishi Exp kishi $
@author KISHI Yasuhiro
*/
public class ResponseHeaderObtainer {
private HttpURLConnection connection = null;
private List headers = null;
public ResponseHeaderObtainer( HttpURLConnection connection ) throws Exception {
this.connection = connection;
try {
obtain();
} catch ( Exception e ) {
throw e;
}
}
public List getHeaders() {
return headers;
}
private void obtain() throws Exception {
if ( headers == null ) {
headers = new LinkedList();
}
// レスポンスヘッダを読み取る
try {
int n = 1;
String key;
while ( ( key = connection.getHeaderFieldKey( n ) ) != null ) {
String value = connection.getHeaderField( n );
String[] pair = new String[ 2 ];
pair[ 0 ] = key;
pair[ 1 ] = value;
headers.add( pair );
n++;
}
} catch ( Exception e ) {
throw( e );
}
}
}
::::::::::::::
SummaryInfo.java
::::::::::::::
/**
* $Id: extractor.html,v 1.1 2009/06/22 16:12:09 kishi Exp kishi $
* @author KISHI Yasuhiro
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class SummaryInfo {
private long accessCount;
private long blogCount;
private String title;
public void setAccessCount( long accessCount ) {
this.accessCount = accessCount;
}
public void setBlogCount( long blogCount ) {
this.blogCount = blogCount;
}
public void setTitle( String title ) {
this.title = title;
}
public long getAccessCount() {
return accessCount;
}
public long getBlogCount() {
return blogCount;
}
public String getTitle() {
return title;
}
}
■実行結果
$ ./extractor.sh 8000 8030
User-Agent: 544ffa7ca2f97f84857acba52bdc583b1404218b
インデックス: 8000 応答コード: 200 所要時間: 2000 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 66 タイトル: Doblog - 交流道場 - URL: http://www.doblog.com/weblog/myblog/8000
User-Agent: 01FFE43D12E0400B257AD161B318CEF04B7121EF
インデックス: 8001 応答コード: 200 所要時間: 328 msec
ポイント: 345.0 総ブログ数: 1 総アクセス数: 345 タイトル: Doblog - le courrier - URL: http://www.doblog.com/weblog/myblog/8001
User-Agent: 01ffe43d12e0400b257ad161b318cef04b7121ef
インデックス: 8002 応答コード: 200 所要時間: 1547 msec
ポイント: 50.8 総ブログ数: 5 総アクセス数: 254 タイトル: Doblog - Dear。。。book - URL: http://www.doblog.com/weblog/myblog/8002
User-Agent: EF284957B33699FB934B2146E0707AA3FCE7D5D5
インデックス: 8003 応答コード: 200 所要時間: 344 msec
ポイント: 20.0 総ブログ数: 1 総アクセス数: 20 タイトル: Doblog - UNS digital - URL: http://www.doblog.com/weblog/myblog/8003
User-Agent: 2f1e4912f84a37f2b7c1d0b001a9baa829916132
インデックス: 8004 応答コード: 200 所要時間: 671 msec
ポイント: 19.1 総ブログ数: 24 総アクセス数: 459 タイトル: Doblog - 超多忙サラリーマンの為のインチキ情報起業講座(仮)〜ブログ?メルマガ
?ソーシャルネットワーク?〜 - URL: http://www.doblog.com/weblog/myblog/8004
User-Agent: 72FF8EC032906F099EA989A560C3032B98C1E35D
インデックス: 8005 応答コード: 200 所要時間: 468 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 38 タイトル: Doblog - Corum TV - URL: http://www.doblog.com/weblog/myblog/8005
User-Agent: e080666fe8d8c7ce4afb887521bf9a6de3dbb65a
インデックス: 8006 応答コード: 200 所要時間: 844 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 20 タイトル: Doblog - TEN DENDEな日記 - URL: http://www.doblog.com/weblog/myblog
/8006
User-Agent: A24F5E4B77C5F5E1925F17D31933A77BCE2C06AD
インデックス: 8007 応答コード: 200 所要時間: 4110 msec
ポイント: 657.4 総ブログ数: 41 総アクセス数: 26953 タイトル: Doblog - よみがえれ!バサラの精神 - URL: http://www.doblog.com/weblog/myblog
/8007
User-Agent: 24C27625E52B2E8F12DF27F29EC6A66C1965D267
インデックス: 8008 応答コード: 200 所要時間: 625 msec
ポイント: 16.3 総ブログ数: 4 総アクセス数: 65 タイトル: Doblog - ジンベースで - URL: http://www.doblog.com/weblog/myblog/8008
User-Agent: 46AA3D4D22BCF6BAD23294B3F2E6CB2BF33914A3
インデックス: 8009 応答コード: 200 所要時間: 422 msec
ポイント: 436.1 総ブログ数: 23 総アクセス数: 10030 タイトル: Doblog - JR. OUME ONLINE - URL: http://www.doblog.com/weblog/myblog/8009
User-Agent: 82586ac14f2b02b7d03d2290a439073f2d7659d0
インデックス: 8010 応答コード: 200 所要時間: 844 msec
ポイント: 57.2 総ブログ数: 13 総アクセス数: 744 タイトル: Doblog - −いのセンス− - URL: http://www.doblog.com/weblog/myblog/8010
User-Agent: 1103d88dc321931fd021d0680383b260ed44ed8d
インデックス: 8011 応答コード: 200 所要時間: 984 msec
ポイント: 107.5 総ブログ数: 50 総アクセス数: 5377 タイトル: Doblog - タワゴト妄想日記 - URL: http://www.doblog.com/weblog/myblog/8011
User-Agent: 5A26F1BD606EC0EF597293154526EEC76C0DE628
インデックス: 8012 応答コード: 200 所要時間: 1360 msec
ポイント: 484.3 総ブログ数: 4 総アクセス数: 1937 タイトル: Doblog - たまこよみ - URL: http://www.doblog.com/weblog/myblog/8012
User-Agent: 0A166DDE2B95CB94460E3FCA2266E361A00303DF
インデックス: 8013 応答コード: 200 所要時間: 218 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 0 タイトル: Doblog - メッセージ URL: http://www.doblog.com/weblog/myblog/8013
User-Agent: 20a08cb2da07c68d564bbfb35575289267f473aa
インデックス: 8014 応答コード: 200 所要時間: 328 msec
ポイント: 32.0 総ブログ数: 1 総アクセス数: 32 タイトル: Doblog - MARI & Co. - URL: http://www.doblog.com/weblog/myblog/8014
User-Agent: 20A08CB2DA07C68D564BBFB35575289267F473AA
インデックス: 8015 応答コード: 200 所要時間: 3172 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 16 タイトル: Doblog - BIODOLL-生体人形実験室 - URL: http://www.doblog.com/weblog/myblog
/8015
User-Agent: 074db073a4f8de2450ecbf8e93d053c34f70fee3
インデックス: 8016 応答コード: 200 所要時間: 407 msec
ポイント: 35.1 総ブログ数: 32 総アクセス数: 1122 タイトル: Doblog - たまねぎ畑の真ん中で - URL: http://www.doblog.com/weblog/myblog
/8016
User-Agent: FF31748A52CB20CCAB449C7B992509D067DA1574
インデックス: 8017 応答コード: 200 所要時間: 219 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 0 タイトル: Doblog - メッセージ URL: http://www.doblog.com/weblog/myblog/8017
User-Agent: ff31748a52cb20ccab449c7b992509d067da1574
インデックス: 8018 応答コード: 200 所要時間: 265 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 22 タイトル: Doblog - 新着情報 - URL: http://www.doblog.com/weblog/myblog/8018
User-Agent: ff043de99ccd6baeddea95d45260b2dc09b1302e
インデックス: 8019 応答コード: 200 所要時間: 297 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 26 タイトル: Doblog - ぺきぺき日記 - URL: http://www.doblog.com/weblog/myblog/8019
User-Agent: ff043de99ccd6baeddea95d45260b2dc09b1302e
インデックス: 8020 応答コード: 200 所要時間: 516 msec
ポイント: 129.0 総ブログ数: 4 総アクセス数: 516 タイトル: Doblog - 桃山演習1年1組 - URL: http://www.doblog.com/weblog/myblog/8020
User-Agent: 62C4DB50CBB134092E77C130FD9CF85B17891B8C
インデックス: 8021 応答コード: 200 所要時間: 3203 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 0 タイトル: Doblog - メッセージ URL: http://www.doblog.com/weblog/myblog/8021
User-Agent: 1d5b1bea9c8c1224e28c7c01096ebe84b6bf7422
インデックス: 8022 応答コード: 200 所要時間: 390 msec
ポイント: 23.6 総ブログ数: 21 総アクセス数: 495 タイトル: Doblog - お小遣いで始めた外為 - URL: http://www.doblog.com/weblog/myblog
/8022
User-Agent: e28e18d7d3a7078b465f32514f88bfbea3c596da
インデックス: 8023 応答コード: 200 所要時間: 219 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 0 タイトル: Doblog - メッセージ URL: http://www.doblog.com/weblog/myblog/8023
User-Agent: E28E18D7D3A7078B465F32514F88BFBEA3C596DA
インデックス: 8024 応答コード: 200 所要時間: 281 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 19 タイトル: Doblog - WeBLog - URL: http://www.doblog.com/weblog/myblog/8024
User-Agent: 62588F17354516BA5720C2C83FF1E29BAE104784
インデックス: 8025 応答コード: 200 所要時間: 266 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 14 タイトル: Doblog - WeBLog - URL: http://www.doblog.com/weblog/myblog/8025
User-Agent: 62588f17354516ba5720c2c83ff1e29bae104784
インデックス: 8026 応答コード: 200 所要時間: 3250 msec
ポイント: 59.0 総ブログ数: 1 総アクセス数: 59 タイトル: Doblog - ともあきとぶいたろうの冒険 - URL: http://www.doblog.com/weblog/myblog
/8026
User-Agent: 7FB697477A88A5279C74B3739CFAF4904A6A8E5A
インデックス: 8027 応答コード: 200 所要時間: 1281 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 13 タイトル: Doblog - この素晴らしき世界 - URL: http://www.doblog.com/weblog/myblog/8027
User-Agent: A1B104EBCCB3A2DBB94B045D928CD41A6CD3C5FE
インデックス: 8028 応答コード: 200 所要時間: 344 msec
ポイント: 59.0 総ブログ数: 1 総アクセス数: 59 タイトル: Doblog - ホスト菅原の小渉は凄い!! - URL: http://www.doblog.com/weblog/myblog
/8028
User-Agent: a1b104ebccb3a2dbb94b045d928cd41a6cd3c5fe
インデックス: 8029 応答コード: 200 所要時間: 265 msec
ポイント: 0.0 総ブログ数: 0 総アクセス数: 15 タイトル: Doblog - この素晴らしき世界 - URL: http://www.doblog.com/weblog/myblog/8029
User-Agent: FA32FF3F1067FFFA7E7DBCF429987847759074DF
インデックス: 8030 応答コード: 200 所要時間: 328 msec
ポイント: 12.5 総ブログ数: 2 総アクセス数: 25 タイトル: Doblog - its test - URL: http://www.doblog.com/weblog/myblog/8030
戻る