質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1072閲覧

Mechanizeで抽出するデータを細かく指定したい

begenner

総合スコア80

スクレイピング

スクレイピングとは、公開されているWebサイトからページ内の情報を抽出する技術です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/05/06 21:36

編集2020/05/07 10:34

現在某サイトを利用してスクレイピングの勉強をしています。
少しは理解できたと思うのですが、
下記のHTMLコードから

  • <div class="aaa">タグ内のテキスト(3件 - ooopppqqq、yyy、zzz)を抽出したい
  • <span class="bbb">タグ内のテキスト(α、β、θ)は抽出したくない
  • 1件目は一番難儀でαは不要、ooo、aタグ内のテキストppp、aタグ直後のqqqを連結したooopppqqqを取得したい
  • 2、3件目はyyyzzzを取得したい

といった場合のコードの書き方が全くわかりません(m_ m)
もしわかる方がいらっしゃればご教授いただきますようよろしくお願いいたします(m
_m)

html

1<div class="list"> 2 <ol> 3 <li> 4 <div class="aaa"> 5 <span class="bbb">α</span> 6 ooo<a href="site_url">ppp</a>qqq 7 </div> 8 </li> 9 <li> 10 <div class="aaa"> 11 <span class="bbb">β</span> 12 yyy 13 </div> 14 </li> 15 <li> 16 <div class="aaa"> 17 <span class="bbb">θ</span> 18 zzz 19 </div> 20 </li> 21 </ol> 22</div>

動作環境

Ruby2.5.7
Mechanize2.7.6

期待する動作

  • <div class="aaa">タグ内のテキスト(3件 - ooopppqqq、yyy、zzz)を抽出したい
  • <span class="bbb">タグ内のテキスト(α、β、θ)は抽出したくない
  • 1件目は一番難儀でαは不要、ooo、aタグ内のテキストppp、aタグ直後のqqqを連結したooopppqqqを取得したい
  • 2、3件目はyyyzzzを取得したい

ruby

1# 現状だと下記のようにデータが取得されます 2#[ 3# "ooo", 4# "qqq", 5# "yyy", 6# "zzz" 7#] 8 9# 理想は下記のようにデータが取得されること 10#[ 11# "ooopppqqq", 12# "yyy", 13# "zzz" 14#]

コード

スクレイピングするHTML(整形)

  • sample.html

html

1<div class="list"> 2 <ol> 3 <li> 4 <div class="aaa"> 5 <span class="bbb">α</span> 6 ooo<a href="site_url">ppp</a>qqq 7 </div> 8 </li> 9 <li> 10 <div class="aaa"> 11 <span class="bbb">β</span> 12 yyy 13 </div> 14 </li> 15 <li> 16 <div class="aaa"> 17 <span class="bbb">θ</span> 18 zzz 19 </div> 20 </li> 21 </ol> 22</div>

追記:修正したコード(Ruby)

ruby

1require 'mechanize' 2 3agent = Mechanize.new 4# sample.html のコードが含まれるurlから情報を取得 5page = agent.get(url) 6html_infos = page.search('.aaa') 7 8foo = page.xpath("//div[@class='aaa']//text()") 9bar = page.xpath("//div[@class='aaa']/span[@class="bbb"]//text()") 10extracted_datas = (foo - bar).map{|x| x.text.strip}.select{|x| x!=""} 11 12p extracted_datas 13 14# 現状だと下記のようにデータが取得されます 15#[ 16# "ooo", 17# "qqq", 18# "yyy", 19# "zzz" 20#] 21 22# 理想は下記のようにデータが取得されること 23#[ 24# "ooopppqqq", 25# "yyy", 26# "zzz" 27#]

現状のコード

ruby

1require 'mechanize' 2 3agent = Mechanize.new 4# sample.html のコードが含まれるurlから情報を取得 5page = agent.get(url) 6html_infos = page.search('.aaa') 7 8extracted_datas = [] 9html_infos.each do |ele| 10 extracted_datas << ele.inner_text 11end

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

このHTMLだと、<div class="aaa">直下の(空白で無い)テキストノードを取れば良いので、

Ruby

1extracted_datas = 2 page.xpath("//div[@class='aaa']/text()").map{|x| x.text.strip}.select{|x| x!=""}

子ノードがある場合も、それを含めるのか含めないのかを明確にすれば、なんとかなります。

#追記
直下でないテキストノードも対象とする場合。

Ruby

1# div.aaa の中の全テキストノードを取得 2foo = page.xpath("//div[@class='aaa']//text()") 3# span.bbb の中の全テキストノードを取得 4bar = page.xpath("//div[@class='aaa']/span[@class='bbb']//text()") 5# その差を求める 6extracted_datas = 7 (foo-bar).map{|x| x.text.strip}.select{|x| x!=""}

1つのdiv.aaaごとに文字列をつなげたいとかだとちょっと面倒だと思います。

#追記2

1つのdiv.aaaごとに文字列をつなげたいとかだとちょっと面倒だと思います。

そうでも無かった。

Ruby

1extracted_datas = 2page.xpath("//div[@class='aaa']").map do |div| 3 foo = div.xpath(".//text()") 4 bar = div.xpath(".//span[@class='bbb']//text()") 5 (foo-bar).map{|x| x.text.strip}.join 6end

投稿2020/05/06 23:12

編集2020/05/07 11:40
otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

begenner

2020/05/07 10:36 編集

期待したとおりの値が取得できました。ありがとうございます。 ただ私の記述漏れがあり、上記のHTMLコードの中にaタグが記述されているのを見落としていたため、 配列として取得したデータが、1レコード分のデータが分離して2レコード分になってしまいました。 aタグの中のテキストも必要な状況です。 お手数ですが、上記の回答をどのようにすればいいか教えていただけると幸いです。よろしくお願いします(m_ _m) aタグ入りのコードは下記の通りです。 <div class="aaa"> <span class="bbb">α</span>xxx<a href="site_url">あいう</a>xxxx </div>
begenner

2020/05/07 10:39

回答いただいた内容を参考に修正してみましたが、結果は変わりませんでした(m_ _m) 投稿内容に追記しましたので、もしみていただけるならよろしくお願いします(m_ _m)
otn

2020/05/07 11:41 編集

要件を小出しにするのはやめましょう。
begenner

2020/05/07 21:51

期待通りの値が取得できました!! 今後は要件をまとめて掲載できるよう気をつけます(m_ _m) ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問