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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

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

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

Q&A

解決済

2回答

586閲覧

Nokogiri, Xpathでh1タグに挟まれた兄弟タグの数え方

decatail

総合スコア41

Ruby

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

XPath(XML Path)

XML Path Language (XPath; XMLパス言語)は、マークアップ言語 XML に準拠した文書の特定の部分を指定する言語構文の事をいいます。XPathはXMLとは別の構文を使用します。XMLドキュメントの抽象、論理ストラクチャ上で動作します。

0グッド

0クリップ

投稿2023/04/30 03:07

実現したいこと

下手なタイトルですみません。
RubyのNokogiriを使用しています。
次のHTMLでh1タグ(mmmm)に挟まれている兄弟関係にあるdivタグ(oooo)を数え上げる手法があれば教えてください。想定している出力結果としては"[3,2,1]"等です。

HTML

1<div id="CONTENTS_MAIN"> 2 <h1 class="mmmm"></h1> 3 <div class ="oooo"></div> 4 <div class ="oooo"></div> 5 <div class ="oooo"></div> 6 <h1 class="mmmm"></h1> 7 <div class ="oooo"></div> 8 <div class ="oooo"></div> 9 <h1 class="mmmm"></h1> 10 <div class ="oooo"></div> 11 <h1 class="mmmm"></h1> 12</div>

前提

スクレイピングで遊んでいます。
RubyでNokogiri(1.14.3)を使用しています。
他に必要な情報があればどうぞご教授下さい。

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

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

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

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

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

guest

回答2

0

他の回答のコメントに書くべき所を回答に書いてしまったのですが、削除だけするのも何なので、別解を書いておきます。
<div id="CONTENTS_MAIN">の子要素を全部並べて、h1.mmmmでグループに分割して、それぞれでdivを数えます。
クラス名までチェックしたいのか、質問の記述が曖昧なので、タグだけ見るのかクラスも見るのか、それぞれ1例ずつにしています。

Ruby

1counts = doc.css("div#CONTENTS_MAIN > *").slice_when{|x,y| x.name=="h1" && x["class"]=="mmmm"}.map{|x| x.count{|y| y.name=="div"}}

ただし、結果は[0, 3, 2, 1]のように先頭のh1タグの前の個数も数えますので、不要なら結果の先頭を削除。

投稿2023/04/30 08:56

編集2023/04/30 12:17
otn

総合スコア84505

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

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

decatail

2023/04/30 12:54 編集

クラス名の指定の有無まで考慮頂きまして大変ありがとうございます。御提示頂いた書き方ですと、最後のh1タグの後にdivタグが来たとしてもそれも含めて数え上げてくれますね。大変助かりました。ありがとうございました。
guest

0

ベストアンサー

ruby

1require 'nokogiri' 2require 'open-uri' 3 4html = '<div id="CONTENTS_MAIN"> 5 <h1 class="mmmm"></h1> 6 <div class ="oooo"></div> 7 <div class ="oooo"></div> 8 <div class ="oooo"></div> 9 <h1 class="mmmm"></h1> 10 <div class ="oooo"></div> 11 <div class ="oooo"></div> 12 <h1 class="mmmm"></h1> 13 <div class ="oooo"></div> 14 <h1 class="mmmm"></h1> 15</div>' 16 17doc = Nokogiri::HTML(html) 18count = doc.xpath('//h1[@class="mmmm"]').each_cons(2)\ 19 .map{|a, b| (a.xpath('following-sibling::div[@class="oooo"]') & b.xpath('preceding-sibling::div[@class="oooo"]')).count} 20# count = doc.xpath('//h1[@class="mmmm"]').map{|m| m.xpath('following-sibling::div[@class="oooo"]').count}.each_cons(2).map{|a, b| a - b} 21 22p count 23 24# [3, 2, 1]

投稿2023/04/30 04:17

編集2023/04/30 09:16
melian

総合スコア19714

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

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

otn

2023/04/30 08:56

'//h1["mmmm"]' の []内は常に真なので、'//h1' と同じです。 クラス属性を見るには、'//h1[@class="mmmm"]' です。 この例だと、h1タグのクラス属性はすべてmmmmなので、結果はたまたま一致しますが。
melian

2023/04/30 09:16

ありがとうございます、修正しました。
decatail

2023/04/30 12:18

otnさん、melianさん。大変ありがとうございました。御提示頂いたコードを参考にスクレイピングすることが出来ました。重ね重ねお礼申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問