O'Reilly本が災害支援で半額になっているのでAmazon売上ランキングでリストしてみた2(xhtmlからisbnをxpathでぶっこぬき)


このコード
http://d.hatena.ne.jp/qaz76/20110324/1300972727
は、とにかく、ebookのISBNをAWSで加工することだけが目的のコード。



だからLL的に書いてるとはいえ、さすがにISBNが人力編集っていのは身も蓋もない;


っつーことで、
https://www.oreilly.co.jp/ebook/
からisbnをxhtmlをパースしてxpathでぶっこぬくw

今日のTop10

全リストは後半で...
ランキング、動いてますなw

SalesRank |ISBN          |Title
----------+--------------+------------------------------
      1187|    4873114799| プログラマが知るべき97のこと
      1562|    4873113989| Arduinoをはじめよう (Make:PROJECTS)
      2740|    487311456X| Android Hacks ―プロが教えるテクニック & ツール
      5697|    4873113911| JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
      9155| 9784873114293| ソフトウェアアーキテクトが知るべき97のこと
     11294|    4873114535| Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ (Make:PROJECTS)
     12227|    4873113164| デザイニング・インターフェース ―パターンによる実践的インタラクションデザイン
     12616|    4873113733| Head First JavaScript ―頭とからだで覚えるJavaScriptの基本
     15001|    4873114772| Make: Electronics ―作ってわかる電気と電子回路の基礎 ((Make:PROJECTS))
     16177|    4873113075| エンジニアのための時間管理術

コード

package com.amazon.associates.sample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.cyberneko.html.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

//http://commons.apache.org/codec/download_codec.cgi
//... commons-codec-1.4.jar
//http://sourceforge.net/projects/nekohtml/
//... nekohtml.jar
//http://xerces.apache.org/#xerces2-j/
//... xercesImpl.jar
//... xml-apis.jar
public class EbookSalseRank {

	public static void main(String[] args) throws MalformedURLException,
			Exception {
		Map<String, String> params = new HashMap<String, String>();

		params.put("Service", "AWSECommerceService");
		params.put("Operation", "ItemLookup");
		params.put("IdType", "ISBN");
		params.put("SearchIndex", "Books");
		params.put("ResponseGroup", "Medium");

		SignedRequestsHelper srh = new SignedRequestsHelper();

		DocumentBuilder builder = DocumentBuilderFactory.newInstance()
				.newDocumentBuilder();

		List<Document> list = new ArrayList<Document>();

		for (String isbn : getIsbnList()) {
			params.put("ItemId", isbn);
			String content = getContent(new URL(srh.sign(params)));
			list.add(builder.parse(new InputSource(new StringReader(content))));
		}

		showList(list);
	}

	private static List<String> getIsbnList() throws SAXException, IOException,
			XPathExpressionException {
		DOMParser parser = new DOMParser();
		parser.parse("https://www.oreilly.co.jp/ebook/");

		Document document = parser.getDocument();

		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();

		xpath.setNamespaceContext(new NamespaceContext() {

			@Override
			public String getNamespaceURI(String arg0) {
				if (arg0.equals("x"))
					return "http://www.w3.org/1999/xhtml";
				return null;
			}

			@Override
			public String getPrefix(String arg0) {
				return null;
			}

			@Override
			public Iterator<String> getPrefixes(String arg0) {
				return null;
			}
		});

		XPathExpression expr = xpath
				.compile("//x:TABLE[@id='bookTable']//x:TD[@class='isbn']");

		NodeList nodeList = (NodeList) expr.evaluate(document, XPathConstants.NODESET);

		List<String> list = new ArrayList<String>();

		for (int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);
			list.add(xpath.evaluate("text()", node).replaceAll("-", ""));
		}

		return list;
	}

	private static String getContent(URL url) throws Exception {
		StringBuffer sb = new StringBuffer();
		HttpURLConnection con = null;
		BufferedReader br = null;
		try {
			con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod("GET");
			br = new BufferedReader(new InputStreamReader(con.getInputStream(),
					"UTF-8"));

			String s;
			while ((s = br.readLine()) != null) {
				sb.append(s);
				sb.append("\r\n");
			}
		} finally {
			if (br != null)
				br.close();
			if (con != null)
				con.disconnect();
		}

		return sb.toString();
	}

	private static void showList(List<Document> list)
			throws XPathExpressionException {
		XPathFactory factory = XPathFactory.newInstance();
		final XPath xpath = factory.newXPath();

		Document[] docs = list.toArray(new Document[list.size()]);
		Arrays.sort(docs, new Comparator<Document>() {
			@Override
			public int compare(final Document o1, final Document o2) {
				int i = 0;
				try {
					i = Integer.parseInt(xpath.evaluate(
							"/ItemLookupResponse/Items/Item/SalesRank", o1))
							- Integer.parseInt(xpath.evaluate(
									"/ItemLookupResponse/Items/Item/SalesRank",
									o2));
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
				return i;
			}
		});

		System.out.println("SalesRank |ISBN          |Title");
		System.out
				.println("----------+--------------+------------------------------");
		for (Document doc : docs)
			System.out
					.format("%10s| %13s| %s\n",
							xpath.evaluate(
									"/ItemLookupResponse/Items/Item/SalesRank",
									doc),
							xpath.evaluate(
									"/ItemLookupResponse/Items/Item/ItemAttributes/ISBN",
									doc),
							xpath.evaluate(
									"/ItemLookupResponse/Items/Item/ItemAttributes/Title",
									doc));
	}
}

ポイント

htmlパーサ

以前仕事でお世話になったMayaaでも使っているnekohtml
コチラ
http://d.hatena.ne.jp/d-kami/20080715/1216101853
などを参照させていただき使いますた。

やっぱ、javax.xml.xpathでそのまま弄れるのがいいw

xhtmlxpath

一捻りw

		xpath.setNamespaceContext(new NamespaceContext() {
...
				if (arg0.equals("x"))
					return "http://www.w3.org/1999/xhtml";
...
				.compile("//x:TABLE[@id='bookTable']//x:TD[@class='isbn']");

Namespaceは1つだけだからif要らないかな。

というか、このコンテキスト...
Namespaceはxhtmlでは省略されているのに、xpathでは明示しなきゃいけないってのはちょっと気持ち悪いぞ;


全リスト

SalesRank |ISBN          |Title
----------+--------------+------------------------------
      1187|    4873114799| プログラマが知るべき97のこと
      1562|    4873113989| Arduinoをはじめよう (Make:PROJECTS)
      2740|    487311456X| Android Hacks ―プロが教えるテクニック & ツール
      5697|    4873113911| JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
      9155| 9784873114293| ソフトウェアアーキテクトが知るべき97のこと
     11294|    4873114535| Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ (Make:PROJECTS)
     12227|    4873113164| デザイニング・インターフェース ―パターンによる実践的インタラクションデザイン
     12616|    4873113733| Head First JavaScript ―頭とからだで覚えるJavaScriptの基本
     15001|    4873114772| Make: Electronics ―作ってわかる電気と電子回路の基礎 ((Make:PROJECTS))
     16177|    4873113075| エンジニアのための時間管理術
     16403| 9784873113296| JavaScript 第5版
     17769|    4873114381| Head First Rails ―頭とからだで覚えるRailsの基本
     20096|    4873114624| iPhone/iPadゲーム開発ガイド ―Objective-Cで作る2D/3Dゲーム
     20597|    487311361X| ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール
     21264|    4873114713| 言語設計者たちが考えること
     22295| 9784873113692| Head First SQL ―頭とからだで覚えるSQLの基本
     23719|    4873114446| Head First PHP & MySQL ―頭とからだで覚えるWebアプリケーション開発の基本
     25980| 9784873112916| PHP Hacks ―プロが教えるWebプログラミングテクニック
     27540|    4873114683| jQueryクックブック
     30359|    4873114276| 初めてのPerl 第5版
     30752|    4873113679| 初めてのRuby
     31233|    4873113024| Web解析Hacks ―オンラインビジネスで最大の効果をあげるテクニック & ツール
     31248|    4873114500| 正規表現クックブック
     32821|    4873114357| 並行コンピューティング技法 ―実践マルチコア/マルチスレッドプログラミング
     34163|    4873114454| Rubyベストプラクティス -プロフェッショナルによるコードとテクニック
     38992|    4873114268| 実践ハイパフォーマンスMySQL 第2版
     41883|    4873113105| Head Rush Ajax ―学びながら読むAjax入門
     42884| 9784873112770| 入門 GNU Emacs 第3版
     45152|    4873113415| Google Maps Hacks 第2版 ―地図検索サービスをもっと活用するテクニック
     48640|    4873114721| iOS SDK Hacks ―プロが教えるiPhoneアプリ開発テクニック
     49708|    4873111544| UMLデスクトップリファレンス
     50249|    4873113423| プログラミングPHP 第2版
     52130|    4873113865| 実践 Rails ―強力なWebアプリケーションをすばやく構築するテクニック
     52974|    4873113121| Railsレシピ
     56141|    4873114675| JavaによるRESTfulシステム構築
     58197|    4873114039| リファクタリング・ウェットウェア ―達人プログラマーの思考法と学習法
     58789|    4873114179| iPhone SDK アプリケーション開発ガイド
     60071|    4873112540| 入門bash 第3版
     62198| 9784873113852| Subject To Change ―予測不可能な世界で最高の製品とサービスを作る
     62670|    4873114586| クラウド セキュリティ&プライバシー ―リスクとコンプライアンスに対する企業の視点
     65143| 9784873113746| C#クックブック 第3版
     65173|    4873113210| Google Hacks 第3版 ―プロが使うテクニック & ツール 100選
     65593| 9784873111346| Web情報アーキテクチャ―最適なサイト構築のための論理的アプローチ
     66302|    487311313X| 詳解 Linuxカーネル 第3版
     67564|    4873113288| IPv6 エッセンシャルズ 第2版
     68352|    4873113822| Windows PowerShellクックブック
     71352|    4873114101| デザイニング・ウェブナビゲーション ―最適なユーザーエクスペリエンスの設計
     74088|    4873114691| 初めてのプログラミング 第2版
     77328|    4873114020| プロダクティブ・プログラマ -プログラマのための生産性向上術
     78002|    4873111811| Amazon Hacks 世界最大のショッピングサイト完全活用テクニック100選
     78236|    4873112389| Word Hacks ―プロが教える文書活用テクニック
     82606|    4873114233| Real World Haskell―実戦で学ぶ関数型言語プログラミング
     83676|    4873114284| アルゴリズムクイックリファレンス
     84315|    4873113598| 詳説 正規表現 第3版
     84329|    487311389X| ThoughtWorksアンソロジー ―アジャイルとオブジェクト指向によるソフトウェアイノベーション
     87447|    4873113814| Apacheクックブック 第2版 ―Webサーバ管理者のためのレシピ集
     87852|    4873112753| データベース実践講義 ―エンジニアのためのリレーショナル理論 (THEORY/IN/PRACTICE)
     91899|    4873114136| 詳解 OpenCV ―コンピュータビジョンライブラリを使った画像処理・認識
     92696|    4873114764| 検索と発見のためのデザイン ―エクスペリエンスの未来へ
     93385|    4873112575| 初めてのPHP5
     93560|    487311330X| Linuxカーネル クイックリファレンス
     95911|    4873113636| ビューティフルコード
     97876|    4873112885| Binary Hacks ―ハッカー秘伝のテクニック100選
     98987|    4873113482| プログラミングGauche
     99406|    4873112990| アート・オブ・プロジェクトマネジメント ―マイクロソフトで培われた実践手法 (THEORY/IN/PRACTICE)
    101499| 9784873114408| 実用Git
    105096|    4873114128| オープンソースソフトウェアの育て方
    107213|    4873113431| 詳解 MySQL
    107956|    4873113539| RESTful Webサービス
    108862| 9784873111476| RADIUS―ユーザ認証セキュリティプロトコル
    111323|    4873110637| C++プログラミング入門
    114325|    4873114314| オプティマイジングWebサイト ―SEO・サーバ・クライアントの最適化技術
    120989|    4873113938| 初めてのPython 第3版
    121779| 9784873113944| プログラミング言語 Ruby
    124672|    4873112850| Windowsサーバークックブック ―ネットワーク管理者のためのレシピ集
    126321|    4873113377| Mind パフォーマンス Hacks ―脳と心のユーザーマニュアル
    126469|    4873113091| WSHクイックリファレンス 第2版
    129064| 9784873113951| アート・オブ・アジャイル デベロップメント ―組織を成功に導くエクストリームプログラミング
    130119|    4873113113| スケーラブルWebサイト
    130968| 9784873113005| Perlベストプラクティス
    133210|    487311425X| 初めてのJavaScript 第2版
    134111|    4873114209| Head First Statistics ―頭とからだで覚える統計の基本
    135178|    4873114306| ビューティフルアーキテクチャ
    136486|    4873114527| セマンティックWeb プログラミング
    140073|    4873113725| Prototype & script.aculo.us ―JavaScriptライブラリによるAjaxアプリケーション開発
    140495|    4873112818| 初めてのSQL
    147257|    4873113490| Head Firstオブジェクト指向分析設計 ―頭とからだで覚えるオブジェクト指向の基本
    147885|    4873112842| UML2.0クイックリファレンス
    148903|    4873113253| JavaScriptクイックリファレンス
    149405|    4873113652| 初めてのPHP & MySQL 第2版
    154090|    4873110793| 不正アクセス調査ガイド―rootkitの検出とTCTの使い方
    154439|    4873112222| PDF Hacks ―文書作成、管理、活用のための達人テクニック
    160716|    4873113849| Making Things Talk ―Arduinoで作る「会話」するモノたち (Make:PROJECTS)
    161344|    4873113873| 詳説 ActionScript 3.0
    162018| 9784873113586| Ajaxアプリケーション & Webセキュリティ
    162600| 9784873110998| SAN & NASストレージネットワーク管理
    165244|    4873113458| イノベーションの神話
    165588|    487311232X| CSS完全ガイド 第2版
    167020|    4873113172| 入門 UML 2.0
    169826|    4873112826| 入門Webマッピング ―自分で作るオリジナルのデジタル地図
    170133|    4873112567| Apacheセキュリティ
    171763|    4873113059| 続・初めてのPerl 改訂版
    174333|    4873112796| Head First Java 第2版 ―頭とからだで覚えるJavaの基本
    176035|    4873114438| Head Firstネットワーク ―頭とからだで覚えるネットワークの基本
    177850|    4873113717| 初めてのActionScript 3.0 ―Flashユーザーのためのステップアップガイド
    178534|    4873113997| キャパシティプランニング ― リソースを最大限に活かすサイト分析・予測・配置
    182087|    4873113628| Linuxシステムプログラミング
    189307| 9784873113272| ネットワークセキュリティHacks 第2版 ―プロが使うテクニック & ツール 100+
    189477|    4873113881| Tomcatハンドブック 第2版
    189661| 9784873113661| インターフェイス指向設計 ―アジャイル手法によるオブジェクト指向設計の実践
    190167|    4873114349| デザイニング・ウェブインターフェース ―リッチなウェブアプリケーションを実現する原則とパターン
    191771|    4873112761| Python クックブック 第2版
    193180|    4873114462| 続・ハイパフォーマンスWebサイト ―ウェブ高速化のベストプラクティス
    198665|    4873114519| セキュリティの神話
    200705|    4873114004| Railsデプロイ
    201793|    4873114640| Head Firstデータ解析 ―頭とからだで覚えるデータ解析の基本
    201841|    4873114195| Silverlightで開発するデータ駆動アプリケーション
    203149|    4873113067| Linuxサーバ Hacks 2 ―コネクティング、モニタリング、トラブルシューティング
    203564|    4873113970| マスタリングPerl
    207146|    4873113962| プログラミングC# 第5版
    211673|    4873112869| 入門PHPセキュリティ
    214089|    4873113563| Rubyスクリプティングテクニック ―テスト駆動による日常業務処理術
    216210| 9784873112350| Flash Hacks ―プロが教えるテクニック&ツール100選
    222630|    4873112265| Windowsサーバー Hacks ―管理者必携のテクニック & WSHスクリプト 100選
    223435|    4873114225| 組み込みLinuxシステム構築 第2版
    227409|    4873114152| Adobe AIR クックブック ―プロフェッショナルに学ぶRIAプログラミングの実践
    229946|    4873114594| ビューティフルセキュリティ
    230409|    487311215X| Hibernate (開発者ノートシリーズ)
    230793|    4873113903| DNS & BIND 第5版
    231253|    4873113334| Ajax&JavaーJavaプログラマのためのAjaxプライマー
    236810|    4873114241| アート・オブ・アプリケーション パフォーマンステスト
    242602|    4873113083| 802.11無線ネットワーク管理 第2版
    244338|    4873113520| 初めてのFlash Video
    246057| 9784873113548| ネットワークウォリア ―戦う管理者のための知識とテクニック
    248505|    4873112893| Asterisk ―テレフォニーの未来
    255727|    4873113466| Linuxシステム管理
    259103|    4873110610| Javaネットワークプログラミング 第2版
    261935|    4873114608| アプレンティスシップ・パターン ―徒弟制度に学ぶ熟練技術者の技と心得
    264885|    4873113555| インテル スレッディング・ビルディング・ブロック ―マルチコア時代のC++並列プログラミング
    265719|    4873113326| Ajax on Rails
    271270|    4873112281| Knoppix Hacks ―カスタマイズとシステム管理のテクニック
    278611|    4873114667| プログラミングF#
    288058|    4873112907| 詳説 ビジネスプロセスモデリング ―SOAベストプラクティス (THEORY/IN/PRACTICE)
    299470|    4873113261| CとGNU開発ツールによる組み込みシステムプログラミング 第2版
    299813|    4873113369| アート・オブ・SQL ―パフォーマンスを引き出すSQLプログラミング手法
    300252|    487311246X| GDBハンドブック
    303315|    4873112729| プレファクタリング ―リファクタリング軽減のための新設計 (THEORY/IN/PRACTICE)
    303700|    4873114160| エンタープライズ Rails ―企業ユーザのためのWebアプリケーション設計術
    304339|    4873113318| SQL Hacks ―データベースを自由自在に操るテクニック
    310992|    4873113768| bashクックブック
    312683|    4873112516| LinuxデスクトップHacks ―プロが教えるテクニック&ツール100選
    313117|    4873113156| SQLクックブック ―データベースエキスパートのための実践レシピ集
    318581|    4873112524| MySQLクイックリファレンス
    319921| 9784873112664| Podcasting Hacks ―構成、録音、発信の必須テクニック
    328870|    4873113709| JavaScript & DHTMLクックブック 第2版 ―Webエキスパート必携テクニック集
    336177|    4873114322| ウェブアプリケーションのためのユニバーサルデザイン
    342105| 9784873112732| Jakarta Strutsクックブック
    346617|    4873111978| JavaServer Faces完全ガイド
    348586|    4873114659| Erlangプログラミング
    367779|    4873113245| Rubyクックブック ―エキスパートのための応用レシピ集
    372152|    4873112370| Linuxハンドブック ―機能引きコマンドガイド
    375643| 9784873112947| 初めてのC# 第2版
    380792|    4873113830| Head First C# ―頭とからだで覚えるC#の基本
    386468|    4873113237| Ajaxデザインパターン ―ユーザビリティと開発効率の向上のために
    389568|    4873110505| 入門Perl DBI
    393513|    487311392X| Head Firstソフトウェア開発 ―頭とからだで覚えるソフトウェア開発の基本
    395290|    4873114470| マスタリングXMPP
    408489|    4873113032| C++クックブック
    430139|    4873113342| エンタープライズSOA ―ビジネス革新実現に向けたITデザイン
    437611|    4873110785| NFS&NIS 第2版
    443868|    4873113504| Web 2.0ストラテジー ―ウェブがビジネスにもたらす意味
    452370|    4873112680| JBoss (開発者ノートシリーズ)
    502576|    4873112125| Google―電網打尽のインターネット掌握術 (THE MISSING MANUALシリーズ)
    504671|    4873112702| Maven (開発者ノートシリーズ)
    558107|    4873112346| Mono (開発者ノートシリーズ)
    594600|    4873112435| ブラウザ選択の時代を読み解く
    619325|    487311165X| ActionScriptデスクトップリファレンス
    953893|    4873111714| Excelポケットガイド


関連リンク
http://internet.watch.impress.co.jp/docs/news/20110323_434606.html
http://www.oreilly.co.jp/editors/archives/2011/03/deal-of-the-days-support-disater-relief.html?utm_source=oreilly.co.jp=rss10
http://m.japan.cnet.com/#story,35000837
http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?AuthJavaSampleSig2.html

Enjoy!