Google イメージ検索だけ 403 ですか・・・
Java で Google、Yahoo!、Baidu でイメージ検索をした結果の画像 URL を抜き出すコードを書いてみた。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.net.URLEncoder; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ImageSearchParser { private int page; private String prevWord; private String prevEngine; public static final String GOOGLE = "http://images.google.com/images?q=%1$s&start=%2$d&ndsp=%3$d"; public static final String YAHOO = "http://image-search.yahoo.co.jp/search?ei=UTF-8&fr=top_ga1_sa&p=%1$s&b=%2$d&d=%3$d"; public static final String BAIDU = "http://image.baidu.com/i?ct=201326592&cl=2&lm=-1&tn=baiduimage&pv=&word=%1$s&z=0&rn=21&pn=%2$d&ln=2000"; private static String[] parse(String html) { Pattern pattern = Pattern.compile("\"http://[^\"]+\\.(jpg|JPG|png|PNG|gif|GIF)\""); Matcher m = pattern.matcher(html); ArrayList<String> list = new ArrayList<String>(); while (m.find()) { list.add(m.group()); } String[] images = new String[list.size()]; for (int i = 0; i < images.length; i++) { String s = list.get(i); images[i] = s.substring(0, s.length() - 1).substring(1); } return images; } private void setEngineStatus(String engine, String word) { if (engine.equals(prevEngine) && word.equals(prevWord)) { page++; } else { prevEngine = engine; prevWord = word; page = 0; } } private String[] fromSearchEngine(URL url) throws IOException { URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuffer sb = new StringBuffer(); while (true) { String line = br.readLine(); if (line == null ) { break; } sb.append(line); } br.close(); return parse(new String(sb)); } public String[] fromYahoo(String word) throws IOException { setEngineStatus(YAHOO, word); String query = String.format(YAHOO, URLEncoder.encode(word, "UTF-8"), page, 24); URL url = new URL(query); return fromSearchEngine(url); } public String[] fromGoogle(String word) throws IOException { setEngineStatus(GOOGLE, word); int start = page * 20; int count = (page + 1) * 20; String query = String.format(GOOGLE, URLEncoder.encode(word, "UTF-8"), start, count); URL url = new URL(query); return fromSearchEngine(url); } public String[] fromBaidu(String word) throws IOException { setEngineStatus(BAIDU, word); int start = (page + 1) * 16; String query = String.format(BAIDU, URLEncoder.encode(word, "UTF-8"), start); URL url = new URL(query); return fromSearchEngine(url); } public static void main(String[] args) { ImageSearchParser parser = new ImageSearchParser(); try { for (int i = 0; i < 20; i++) { // String[] images = parser.fromYahoo("ガンダム"); String[] images = parser.fromGoogle("ガンダム"); // String[] images = parser.fromBaidu("ガンダム"); for (String image : images) { System.out.println(image); } } } catch (Exception e) { e.printStackTrace(); } } }
Android でデモみたいな感じで使いたいので Google が適しているんだけど、なぜか Google は URLConnection からアクセスすると 403 を返す。他の検索エンジンで試してみたら、問題なく抽出できた。Google 側の問題(というか制限)っぽくて、調べるの面倒だな・・・。
Yahoo! を使うぐらいなら、画像共有サイトを使ったほうがよっぽどいい。でもそうすると、デモとしての公平さがなくなってしまうような気がする。やっぱり Google で何でダメなのか調べてみよう。さすがに Google が Java で実装したブラウザからはアクセスを受け付けない、なんてことはないと思うから、何か方法があるはず、きっと。