• 締切済み

Ruby初学者です。

Ruby初学者です。 スクレイピングをしています。 Capybara + PhantomJSを用いているのですが(動的要素も取得したいため)、 session.visit "sample.com" variable = session.find_all(:xpath,"//a[contains(text(), "なんとか")]") puts variable といったコードを書くと #<Capybara::Result:0x0325d6honyaefccf0f8> という風な表示がされてしまいます。 上記の例に限らず、xpathで抽出したものをputs等を用いて表示しようとすると、上述のようにわけのわからん表示が出てきて困ります。 Nokogiriだとputsを使うとDOM?html?がそのまま文字通り表示されてくれるのですが。。 Capybaraだと何らかの変換を行うような処理がされてしまっているのですかね。(というかputsでコードを表示するような目的のものではない?) 解決方法(抽出したコードをputsでそのまま表示する方法)があれば教えてください。

  • Ruby
  • 回答数1
  • ありがとう数1

みんなの回答

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.1

>Nokogiriだとputsを使うとDOM?html?がそのまま文字通り表示されてくれるのですが。。 >Capybaraだと何らかの変換を行うような処理がされてしまっているのですかね。(というかputsでコードを表示するような目的のものではない?) いやいや、逆です。Nokogiriが、テキスト化するようなメソッドを定義しているので見て分かるように表示され、Capybaraでは定義していないから、そのまま出てきます。 Capybaraは使ったことないですが、textメソッドで、innerHTMLを取得できるようですよ。

ont_rt
質問者

お礼

なるほどです。 なんか直観には反してますが…ブラウザ側でもnokogiriと同じようにテキスト化するメソッドを定義しているのであって、本当はcapybaraと同じようなResult:0x0325d6honyaefccf0f8みたいな表示なんでしょうか? 兎に角、textメソッドを使ってみたいと思います。ありがとうございます

関連するQ&A

  • Xpathがわからない。

    capybaraとXpathを使ってrubyスクレイピングをしようとしています。 まず添付画像を御覧ください。 ゴールは添付画像のurl部分を(文字列として)抽出することです。(末尾がclans/7.pngみたいになってるやつです) 条件として、添付画像のように、親要素の親要素のクラスに "checkedin"を含むこと。 (画像では省略されていますが、本来のソースコードでは添付画像の一番上の要素に類するものがいくつも並んでいます。その中から、画像のように "checkedin" を含むものを抽出しようとしています) 親要素の親要素の条件を指定しない場合は images = session.find_all(:xpath, '//img[contains(@src,"clans")]') puts images[i][:src] といったコードでURLを抽出できたのですが、上述の条件を指定する場合にどのような記述をすれば良いかわかりません。 checkedin = session.find_all(:xpath, 'tr[contains(@class,"checkedin") and .//img[contains(@src,"clans")]]') と書いたり他色々試しましたが、全てエラーです。 上述の条件を指定して記述するにはどうすればいいのでしょうか。。 (先祖要素の条件指定でなく、まず先祖要素の条件を指定してから子要素のurl抽出をするのもあると思いそれっぽい手法を試しましたが、capybaraそのものが良くわかっておらずエラーになります) (ちなみにcapybaraを使っているのは、以前質問した時におすすめされたからです。 詳細URL→https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13198824358 本当はnokogiriでやりたかったのですが、nokogiriですとurl部分が正常に取得できませんでした。 nokogiriでもurl部分を正しく抽出できる方法があれば是非教えてください。capybaraよりnokogiriの方が使いやすいので。。) 質問の回答になっていないそもそも論は禁止でお願いします。(python使え等)

  • Nokogiriスクレイピングがうまくできない。

    Nokogiriスクレイピングがうまくできない。 RubyのNokogiriを利用して、下記サイトのデータを整理するためにスクレイピングをしようと思っています。 https://sv.j-cg.com/compe/view/entrylist/1274 具体的には、サイト中部の「登録デッキ」の一覧にある使用クラスのデータをまとめるプログラムを組もうと思っています(添付画像参照)。 XPathのサイトを参考にしつつ、試しにこの使用クラスの画像データをテキストで出力するため以下のコードを組んで実行しました。 require 'nokogiri' require 'open-uri' url = 'https://sv.j-cg.com/compe/view/entrylist/1274' charset = nil html = open(url) do |f| charset = f.charset f.read end doc = Nokogiri::HTML.parse(html, nil, charset) p doc.xpath('//img[contains(@src,"clans")]') ですが、 [] と表示されるだけで何も取得できません。 containsの引数を(取得対象のimg要素内の)どの値に変えて試しても、色んな表示が出はするのですが肝心の画像URLの部分が取得できません。 (ページのソースコードを見た所、使用クラスの判別が画像URLでしか出来ないため、URLをまず取得しないことには目的を達成できないだろう、という前提で話しています。) 私の推測では、どうやらURL部分だけjsonファイルらしい(他者には見られない)外部のファイルから引っ張ってきているため、プログラムから読み取ろうとしてもうまくURLを引用できないのだと思ってます。 ですが、ブラウザ上の検証ツールではURLが表示されるのにプログラムでは正しく読み込めないのが疑問です。 何にせよ、うまく使用リーダーを整理する方法があったら教えていただきたいと思います。 (ちなみにスクレイピングで画像URL等を取得した後のうまい整理方法も現段階ではよくわかっていないですが、とりあえずこのURLデータ取得だけでもまず理解してからということで質問をしています。)

  • Ruby Selenium リンクの取得方法

    こんばんは。 Ruby初心者ですが、現在、Selenium Webdriver、chromeにはまり、スクレイピングのような事をしています。 そんな中で困っている事があるのですが、 とあるサイトの画像URLを取得、テキストに追記で書き出ししようと色々と調べたのですが全く分からず困っています。 <div class="hoge"> <img src="http://hoge" alt=""> </div> htmlはこんなようでxpathは/hoge/imgと仮定します。 open("hoge.txt", "a"){|f| output = driver.find_element(:xpath, '/hoge/img') f.puts "#{output.text}" } のように書いてみたもののテキストに改行しか出力されない状態です。 何卒どうかご教授、よろしくお願いします。

    • ベストアンサー
    • Ruby
  • 動的なページのスクレイピング

    動的なページのスクレイピング まず下記のurl御覧ください。 https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q131988243... これで「静的なページの」スクレイピングできるようになったはいいのですが、問題はここからです。 https://sv.j-cg.com/compe/view/entrylist/1489 ↑このような、「ある程度スクロールすると追加でコンテンツが読み込まれるページ」については、正しくスクレイピングできませんでした。 「JavaScriptを実行させて、変化後の要素を取得する」ためにヘッドレスブラウザ(phantomjs)を使っているはずなのに、これは腑に落ちなさすぎるんですが。。 ググったところ、やっぱり「phantomjsを使う」のは正しい解決法のようなんですが、 (これとか→https://ja.stackoverflow.com/questions/19681/nokogiri%E3%81%A7%E5%8...) やっぱり追加後のDOM?については解析できませんでした。 JCGのサイトについてはスクロール時に読み込まれるのはjavascriptの仕様ではないのか、はたまたコードがよくないのか… 教えてください。

  • 配列出力をカンマ区切りに変換(PHP)

    DOMを使ってテーブルのスクレイピングをしたいと考えています。 【sample.html】 <table id="rates"> <tr> <th>施設名</th> <th>所在地</th> </tr><tr> <td>大谷地</td> <td>東3丁目3-20</td> </tr><tr> <td>札幌</td> <td>東1丁目1-20</td> </tr></table> 【scre.php】 <?php $entries = []; $dom = new DOMDocument; @$dom->loadHTMLFile('sample.html'); $xpath = new DOMXpath($dom); foreach ($xpath->query('//tr') as $i => $node) { if (!$i) { continue; } $entries[] = [ $xpath->evaluate('string(td[0])', $node), $xpath->evaluate('string(td[1])', $node), ]; } echo "<pre>"; print_r($entries); echo "</pre>"; ?> *************** 結果(出力値) *************** Array ( [0] => Array ( [0] => 大谷地 [1] => 東3丁目3-20 ) [1] => Array ( [0] => 札幌 [1] => 東1丁目1-20 ) 【やりたいこと】 この結果をカンマ区切りとして抽出したいと考えています。 ***************** 希望結果(希望出力値) ***************** 大谷地,東3丁目3-20 札幌,東1丁目1-20 また、このテーブルは別途CSVファイルに落とす予定のため、 echo $data; という形で出力可能なようにしたいと考えています。 初心者的質問で大変恐縮ですが、どうすればいいかご教授いただけましたら幸いです。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • Mac OSX LionでCGI/Ruby動かず

    Mac OSX Lionを使っています。 CGIでRubyを使いたいと思い、 以下のことを試したのですが、 500 Internal Server Error となってしまいます。 ◆やったこと 以下のファイルを /Library/WebServer/CGI-Executables に置きました。 (改行コードはLFとしました) --test.cgi--- #!/usr/bin/ruby print "Content-Type: text/html¥n¥n" puts "Hello Ruby" ----- そしてchmod 777としてブラウザから http://localhost/cgi-bin/test.cgi にアクセスしたところ、 500 Internal Server Error となってしまいます。 その際の/var/log/apache2/error.logは、 Premature end of script headers: test.cgi とだけ表示されます。 なんだか一番最初の所でつまづいてしまい、 めげそうになっております。 よろしくご教授ください。

    • ベストアンサー
    • CGI
  • RubyのHTMLパーサーで複数のタグを抽出したい

    現在、Rubyを用いて あるWebページから特定のタグの要素を抽出して テキストデータに出力したいと思い、プログラムを書いているのですが、 途中で行き詰ってしまいました。 ちなみにHpricotやNokogiriといったHTMLパーサーを試してみました。 パーサーを使うのは初めてです。 例えば以下のようにHTML文書に抽出したい部分がDIVタグとPタグに囲まれていた場合、 ===================================== ・・・ <div class="content"> <div class="header">不要部分</div> <div class="title">抽出したい文字列1</div> <div class="subtitle">抽出したい文字列2</div> <div class="subtitle">抽出したい文字列3</div> <p class="paragraph">抽出したい文字列4</p> <p class="paragraph">抽出したい文字列5</p> <div class="comment">抽出したい文字列6</div> <div class="footer">不要部分</div> </div> ・・・ ===================================== このHTMLからまずは 抽出したい文字列1 抽出したい文字列2 抽出したい文字列3 抽出したい文字列4 抽出したい文字列5 抽出したい文字列6 といった出力が得たいのです。 プログラムも書いてみました。 ===================================== #ドキュメント全体を取得(dataにはHTMLの文字列が入っている) html = Hpricot(data) #内容部分(contentクラスのdiv)を取得(CSSセレクタで記述) content = html/"div.content" ===================================== ここまでは良いのですが、 そのあと、div要素を取り出すだけであれば headerクラスと、footerクラスを抽出しないように ===================================== (content/"div:not(.header):not(.footer)").each{ |line| puts line.inner_html } ===================================== とすることで、 抽出したい文字列1 抽出したい文字列2 抽出したい文字列3 抽出したい文字列6 が得られますが、pタグをカンマでdivの前に追加して ===================================== (content/"p,div:not(.header):not(.footer)").each{ |line| puts line.inner_html } ===================================== のようにすると、 抽出したい文字列4 抽出したい文字列5 抽出したい文字列1 抽出したい文字列2 抽出したい文字列3 抽出したい文字列6 のように出力されます。 同様にdivの後にpを追加し ===================================== (content/"div:not(.header):not(.footer),p").each{ |line| puts line.inner_text } ===================================== のようにすると 抽出したい文字列1 抽出したい文字列2 抽出したい文字列3 抽出したい文字列6 抽出したい文字列4 抽出したい文字列5 のようになってしまいます。 つまり、複数のタグを指定すると、指定した順序で抽出されるようです。 代わりに子供すべてを列挙するchildのようなものがあるかと、調べてみたのですが、 どうやらそのような書き方はないようです。 複数のタグを含む場合にはHTMLパーサーでは解析できないのでしょうか。 パーサーは抽出時に順番を保証はしてくれないのでしょうか。 あきらめて、正規表現で抽出しようと思いましたが、 ===================================== <div class="comment"> <div class="comment_header">ごちゃごちゃ</div> <div class="comment_body">抽出したい要素6</div> </div> ===================================== などDIVが入れ子となっている場合に、 非常にややこしく感じたので お手上げ状態です。 どのように、解決できるでしょうか。 よろしくお願いします。

    • ベストアンサー
    • Ruby
  • スクレイピングPHPにおける複数spanについて

    外部のホームページのソースを拾いRSS化するPHPを作成しました。 ***************************************** 外部ホームページ http://hoge.com/index.html ***************************************** <html> <table class="Table100"> <tr> <th class="Name"><h1>えんどう豆</h1></th> <td class="Price">254</td> <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> </tr> </table> </html> ***************************************** スクレイピングPHP http://hagedebu.jp/index.php  ***************************************** <?php class SimpleXMLExtended extends SimpleXMLElement { public function addCData($data) { $dom = dom_import_simplexml($this); $dom->appendChild($dom->ownerDocument->createCDATASection($data)); } } $xml = new SimpleXMLExtended('<rss version="2.0"></rss>'); $channel = $xml->addChild('channel'); $channel->addChild('title', 'TEST RSS'); $dom = new DOMDocument; @$dom->loadHTMLFile('http://hoge.com/index.html'); $xpath = new DOMXPath($dom); foreach ($xpath->query('//*[@class="Table100"]') as $node) { $item = $channel->addChild('item'); $item->addChild('description')->addCData(implode('<br>', [ $xpath->evaluate('string(.//*[@class="Name"]/h1)', $node), $xpath->evaluate('string(.//*[@class="Price"])', $node), $xpath->evaluate('string(.//*[@class="maker"]/span)', $node), ])); } header('Content-Type: application/xml; charset=utf-8'); $xml->asXML('php://output'); ************************************************ 問題点 このPHPでは、 えんどう豆 254 メーカー と表示されてしまいます。 <td class="maker"> <span class="a1">メーカー</span> <span class="a2">遠藤農園</span> </td> class="makerに複数のspanが入っているため、2つめのspanを認識しません。 当方が表示させたいのは下記のようにspanを両方とも表示させたいです。 またはひとつしか表示させることができない場合は、「メーカー」ではなく「遠藤農園」を優先表示させたいです。 このように表示させるためにはどうすればよいでしょうか? 希望表示 えんどう豆 254 メーカー 遠藤農園 または えんどう豆 254 遠藤農園 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • rubyでハングル含むファイル名を読むと文字化け

    ruby 初心者です 環境は以下の通り Windows7 64bit Ruby 2.3.1 状況 rubyでハングル含むファイル名をリネームしたいのですが、 フォルダ内のファイル名を読み込んでputsで表示すると、ハングル文字が「??」に文字化けして、 又、renameを実行するとエラーになります。 ハングル文字化けBJ??になる Windowsのファイル名 999-BJ쏘이-hkqwer-20211115.mp4 rubyで読み込んだ後、putsで確認するとハングルが文字化けする 999-BJ??-hkqwer-20211115.mp4 質問 ハングル文字の文字化けを直すには、どの様に指定すればよいのでしょうか? また、.renameする際、何か指定があれば、知りたいです。 補足) ちなみに、ファイル名が、英数や漢字・かなを含む場合や、 .rb内でファイル名に直接ハングル文字を指定すると、正常にリネーム出来ています。 変更前:999-BJ쏘이-hkqwer-20211115.mp4 変更後:☆korean 259-BJ쏘이-hkqwer-20211115.mp4 補足) ・renameを実行するとエラー ren2.rb:207:in 'rename': Invalid argument @ rb_file_s_rename - (C:USers/xxxxxx/Desktop/☆korean/999-BJ??-hkqwer-20211115.mp4, C:USers/xxxxxx/Desktop/☆korean/☆korean 259-BJ??-hkqwer-20211115.mp4) (Errno::EINVAL) ren2.rb:207:in `rename': Invalid argument @ rb_file_s_rename - (C:Users/xxxxxx /Desktop/☆korean/999-BJ??-hkqwer-20211115.mp4, C:Users/xxxxxx/Desktop/☆korean/ ☆korean 259-BJ??-hkqwer-20211115.mp4) (Errno::EINVAL) ・.openにエンコード指定するとエラーになる Dir.open("#{tr_path}", "rw:sjis:utf-8") do |dir| ren2.rb:48:in `open': wrong number of arguments (given 2, expected 1) (ArgumentError) ・実行したソース ruby ren2.rb # coding: UTF-8 ms_path = "G:\/G_Download\/G_XVIDEOS\/1優良\/☆korean" # 本番用 tr_path = "C:\Users/xxxxxx/Desktop/☆korean" # テスト用 Dir.open("#{tr_path}") do |dir| # テスト用 for tr_name in dir puts tr_name # # # .と..を読み飛ばす # # if tr_name == "." || tr_name == ".." then next end # # 読み込んだファイル名から抽出した文字s_nameで、本番用フォルダーを検索して、 # あれば「☆korean xxx-」を取得する # # # テスト用文字 # s_name = "hkqwer" # # 保存用フォルダを検索して、類似ファイルが存在したら、☆korean xxx-を取得する # Dir.glob("#{ms_path}/*#{s_name}*.mp4") do |x| if File.basename(x).include?("☆korean ") == true then #☆korean か? ms_num = File.basename(x)[0,12] elsif File.basename(x).include?("☆Korean ") == true then #☆Korean か? ms_num = File.basename(x)[0,12] else next end # # 999-を☆korean xxx-で置き換える # new_name = tr_name.gsub("999-", ms_num) # 999-を☆korean xxx-へ置き換える # # 元ファイルを、新ファイル名に変更する # File.rename("#{tr_path}/#{tr_name}", "#{tr_path}/#{new_name}") end end end

    • ベストアンサー
    • Ruby
  • Mechanizeでgetしたpageの文字コード変換

    Mecahnizeを使ってgetしたPageのbodyに対して、 文字コード変換したところ、Pageの内容がほとんど消えてしまいます。 よって、タグのサーチやフォームの操作などで失敗してしまいます。 変換前にlinksメソッドを使うと現象が回避されるのを 発見しましたが理由がわかりません。 コードは以下のような感じです。 agent = WWW::Mechanize.new page = agent.get(url) p page #=>いろいろ表示される WWW::Mechanize::Page #lnks = page.links #=>これがないとpageの内容がおかしくなる #変数lnksは全く使っていない page.body = page.body.toutf8 # UTF8に変換 p page #=> 1回目と比較して内容がほとんどなくなっている #linksメソッドを使えば現象が起きない rubyは1.8.7 p174 i386-mswin32です。 mechanizeは0.9.3です。 nokogiriは1.4.1, 1.3.3です。 理由がわかる方、スマートな回避方法、 このコードで使い続けても問題ないか?など ご教授ください<(_ _)>

専門家に質問してみよう