狠狠撸

狠狠撸Share a Scribd company logo
実践スクレイピング
       不条理な現実との折り合いの付け方




ふるかわだいすけ/mogya.com
ふるかわだいすけ

フリーランスWEBエンジニア


            http://mogya.com/
            http://mogya com/
            Twitter: @mogya



     自己紹介
ふるかわだいすけ

フリーランスWEBエンジニア



            http://maidmail.jp/


     自己紹介
http://oasis.mogya.com/


モバイラーズオアシス
http://oasis.mogya.com/


携帯/スマートフォン対応
実践スクレイピング



  今日のテーマ
はじめてのスクレイピング
?Hpricot
 X th
?Xpath
?店名を取ってみる
実践スクレイピング
?1ページに全部入っている場合
 id
?id=xxx方式
        方式
?一覧ページ→详细ページ
?「次へ」対応
 「次へ 対応
現実のスクレイピング
まとめ


          目次
photo by Big Ben(Gaijin Bikers)




はじめてのスクレイピング
例えばこんなページ
    http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01570
こうなっているところから
      http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01570
require 'rubygems'
require 'hpricot'
require 'open-uri'
url =
'http://www mcdonalds map php?strcode=01570'
 http://www.mcdonalds…map.php?strcode=01570
page = Hpricot( open(url).read );nil
page sea c ( S op a e 3 )
page.search(".Shopname h3").inner_te t
                                 e text




            店名を取ってみる
Hpricot
  ? HTMLパーサー
  ? xpathでHTMLから切り出しができる




               Hpricot
page = Hpricot( open(url).read )
page.search(".Shopname h3").inner_text



                           “body div h1”




                           “div#Content1
                           “di #C t t1 h1”




                                 “.content title”
                                  .content_title
                                  (page/".content_title")[0].inner_text



        XPath(XML Path Language)
/html/body/table/tbody/tr[3]/td/
              勝手にtbodyとか補足する点に注意


Firebugを使うとラクチン
        http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01570
require 'rubygems'
require 'hpricot'
require 'open-uri'
         open-uri
url =
'http://www.mcdonalds???map.php?strcode=01570'
page = Hp icot( open( l) ead ) nil
        Hpricot( open(url).read );nil
page.search(".Shopname h3").inner_text




               店名を取ってみる
page = Hpricot( open(url).read )
↓
page = Hpricot( open(url).read );nil

                     irbの場合
userAgent =
  "mogya scraper under construction. ”+
  ”you can contact me at mogya+scraper@mogya.com"
page = Hpricot( open(_url, "User-Agent" => userAgent ).read )




          連絡がつくようにしておく
Require “kconv”
userAgent =
  "mogya scraper under construction. ”+
  ”you can contact me at mogya+scraper@mogya.com"
page = Hpricot( open(url, "User-Agent" => userAgent ).read.toutf8 )



                      ※読みにくいので、以降のサンプルでは省略しました




                  文字コードの問題
? Aj でデ タを動的ロ ド
  Ajaxでデータを動的ロード
   →スクレイピングだとデータが取れない
? JSの読み出し元を見ればいいんじゃね?
?ブラウザでアクセスしてみる
   →403 forbidden
?以降、サイトまるごと403 forbiddenになった
   →「本気だ!」




                         ※このデザインになる前の話


         余談:防衛反応
                  http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01570
photo by Big Ben(Gaijin Bikers)




実践スクレイピング
http://www.burgerkingjapan.co.jp/locations/




1ページに全部入っている場合
                                                 http://www.first-kitchen.co.jp/shop/
バーガーキング
      http://www.burgerkingjapan.co.jp/locations/
require 'rubygems'
     i ' b         '
require 'hpricot'
require 'open-uri'
url = 'htt //
  l 'http://www.burgerkingjapan.co.jp/locations/'
                    b   ki j         j /l ti   /'
page = Hpricot( open(url).read );nil

page.search( li dl ).each{|part|
page search(".li dl") each{|part|
   p part.search("dd h4 a").inner_text
}




                     バーガーキング
                                              http://www.burgerkingjapan.co.jp/locations/
颈诲=虫虫虫虫方式
     http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01578
require 'rubygems'
require 'hp icot'
 eq i e 'hpricot'
require 'open-uri?
url_template
url template =
     'http://www.mcdonalds ??? strcode=%05i'
0.upto(10000){|i|
       url = sprintf(url_template,i)
       page = Hpricot( open(url).read );nil
       p page search(" Shopname h3") inner text
         page.search(".Shopname h3").inner_text
       sleep 3
}



                 颈诲=虫虫虫虫方式
                          http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01578
新店舗情報を見ると idのmax値がわかることが多い
新店舗情報を見ると、idのmax値がわかることが多い



  颈诲=虫虫虫虫方式
         http://www.mcdonalds.co.jp/shop/map/map.php?strcode=01578
飛び飛びで見て最低値を推測

0.step(10000,100){|i|
        url = sprintf(url template i)
              sprintf(url_template,i)
        page = Hpricot( open(url).read );nil
        p "#{url}:"+page.search(".Shopname h3").inner_text
        sleep 3
}




                        颈诲=虫虫虫虫方式
飛び飛びで見て最低値を推測

0.step(10000,100){|i|
        url = sprintf(url template i)
              sprintf(url_template,i)
        page = Hpricot( open(url).read );nil
        p "#{url}:"+page.search(".Shopname h3").inner_text
        sleep 3
}




                        颈诲=虫虫虫虫方式
一覧ページ→详细ページ
        http://www.bagus-99.com/company/shop.html
一覧ページ→详细ページ
        http://www.bagus-99.com/company/shop.html
require 'rubygems'
  q         yg
require 'hpricot'
require 'open-uri'
archive_url = 'http://www.bagus-99.com/netcafe/store/'
archive_page = Hpricot( open(archive_url).read );nil
archive_page.search("td.darker2/a").each{|url_part|
      url = archive_url + url_part['href']
      page = Hpricot( open(url).read ) il
                   i (      ( l)     d );nil
         以下略
      sleep 1
}




             一覧ページ→详细ページ
                                                http://www.bagus-99.com/company/shop.html
「次へ」対応
         http://www.mapion.co.jp???search=mapAreabtn
「次ページへ」がある時




「次ページへ」がない時
 次ペ ジへ」がない時




XPATHではムリ!




              「次へ」対応
                       http://www.mapion.co.jp???search=mapAreabtn
def parse(url)
    p     ( )
        page = Hpricot( open(url).read )
        page.search(".address").each{|part|
           p part.search("h2").inner_text
        }
        next_url =
           (page.inner_html.scan(
             /href="(.*)"><strong>次ページへ/
             /        "( *)"            次    ジ /
           )[0][0]) rescue nil
        if (next_url)
           parse("http://www.mapion.co.jp"+next_url)
                 ("htt //            i     j "+  t l)
        end
end

url = “http://www.mapion.co.jp/c/f????admi3=13101???"
parse(url)




                      「次へ」対応
                                              http://www.mapion.co.jp???search=mapAreabtn
photo by Big Ben(Gaijin Bikers)




現実のスクレイピング
现実1:データ大杉
       http://www.doutor.co.jp/shopsearch/index.html#
→ 47回回せばOK?

现実1:データ大杉
            http://www.mapion.co.jp???BT=all
现実1:データ大杉
            http://www.mapion.co.jp???BT=all
URLをじーっと眺めると。
1.東京都の各エリア
http://www.mapion.co.jp/c/f????&admi2code=13&BT=all&admi3=13101&search.x=15&search.y=8
http://www mapion co jp/c/f?   &admi2code 13&BT all&admi3 13101&search x 15&search y 8
http://www.mapion.co.jp/c/f????&admi2code=13&BT=all&admi3=13102&search.x=25&search.y=5
:
2.それ以外の県
  . れ以外 県
http://www.mapion.co.jp/c/f????&admi2code=40&mx=100&vp=10&BT=all
http://www.mapion.co.jp/c/f????&admi2code=41&mx=100&vp=10&BT=all



→2パターンに分けてスクレイピング
      に分        グ




                       対処1:地道に対応
贵濒补蝉丑の検索フォーム
                                    検索




现実2:强敌贵濒补蝉丑
      http://sp.chizumaru.com/dbh/lotteria/top.aspx?account=lotteria
贵濒补蝉丑の検索フォーム
                                    検索




现実2:强敌贵濒补蝉丑
      http://sp.chizumaru.com/dbh/lotteria/top.aspx?account=lotteria
现実2:强敌贵濒补蝉丑
              http://sp.chizumaru.com/???&arg=
http://sp.chizumaru.com/dbh/lotteria/detailmap.aspx?accou
nt=lotteria&accmd=0&arg=&c1=&c2=&c3=&c4=&c5=&c6=
&c7 &c8 &c9 &c10 &c11 &c12 &c13 &c14 &c15 &c16
&c7=&c8=&c9=&c10=&c11=&c12=&c13=&c14=&c15=&c16
=&c17=&c18=&c19=&c20=&c21=&c22=&c23=&c24=&c25
=&c26=&c27=&c28=&c29=&c30=&mode=11&key=&pg=1&
                    ad &b d
                    adr=&bid=113106
                                3 06

                                                 6桁とかw


      现実2:强敌贵濒补蝉丑
                      http://sp.chizumaru.com/dbh/lotteria/detailmap.aspx???bid=113106
http://sp.chizumaru.com/dbh/lotteria/detailmap.aspx?accoun
                  t=lotteria&bid=113106




      现実2:强敌贵濒补蝉丑
鉄壁!
?ページリスト:取れない(Flashだから)
?一覧ページのURL:取れない
      (座標指定なのでパターンを読めない)
?個別ページ:id多すぎ




         现実2:强敌贵濒补蝉丑
対応:偶然発见!
http://www.pronto.co.jp/solare/
          注)BGMが鳴ります




現実3:強敵Flash2
数が少ないので手作业で片付けましたw




     対策3:あきらめる
余谈:渡る世间に鬼はなし
               http://www.manboo.co.jp/
余谈:渡る世间に鬼はなし
               http://www.manboo.co.jp/
现実4:罢补产濒别レイアウト
现実4:罢补产濒别レイアウト
XPATHがこんなふうになる
 page.search("/html/body/table/tr[3]/td/table/tr/td/table/tr/td[2]/tab
 le/tr[3]/td/table/tr[3]/td/table/tr/td/table/tr/td/a )
 le/tr[3]/td/table/tr[3]/td/table/tr/td/table/tr/td/a”)

ひどい場合、そもそもXPATHで表現できないことも


対応
 ?1カ所くらいclassがついていることもある
 ?FireBugで何とかなる間はなんとかする
 ?どうにもならない時は、正規表現で取得




           现実4:罢补产濒别レイアウト
现実5:滨苍惫补濒颈诲な贬罢惭尝
现実5:滨苍惫补濒颈诲な贬罢惭尝
問題:xpathで読めなくなってしまう
対策:読み込んだタイミングで直してしまう

page =
  Hpricot(
  H i t(
    open(url).read.gsub(
        "</script>?n<body>","</script>?n“
         </script>?n<body> </script>?n
    )
  );nil




         対策:アドホックに直す
th便利
?xpath便利
?スクレイピングは個別対応の嵐
 スクレイピングは個別対応の嵐
?validなHTMLを書きましょう




         まとめ
おしまい
おしまいだってば!
もうないよ!
时间があまった?
じゃあしょうがない
About
モバイラーズオアシス
モバイラ ズオアシス


    おまけ
「情報はどこから?」
 情報はどこから?」




  よくいただく质问
こたえ
ブログ
???正直ムリ(><)
twitter
? t itt で「電源 OR コンセント -切」をwatch
  twitterで「電源    ンセント 切 を t h
? 99%はどうでもいい話だけど、
    高速で読み飛ばせるので対応可能
? 敵はbotと診断メーカー




               twitter
? t itt で「電源 OR コンセント -切」をwatch
  twitterで「電源    ンセント 切 を t h
? 99%はどうでもいい話だけど、
    高速で読み飛ばせるので対応可能
? 効能
   ?電源情報収集
   ?宣伝
   ?SEO
    顧客の声を聞く
   ?顧客の声を聞く




               twitter
on ExpressionEngine




   バックエンド
管理を颁惭厂に投げる
システム构成
? Ce tOS5 3
  CentOS5.3
? Apache2.2.3
? E pressionEngine v.1.6.4
  ExpressionEngine 1 6 4
? MySQL 5.0
? jQuery 1.3.2
         132
? GoogleMapsAPI




               システム构成
システム构成
                        ee_Net_UserAgent_Mobile
                        ee Net UserAgent Mobile
通常のリクエスト
通常 リク  ト
           Expression   spot_search
結果ページの       Engine
リクエスト



                            DB
検索クエリ      Search.php




           システム构成

More Related Content

実践スクレイピング