スクレイピングでのXPathの使い方について質問です。


Web::ScraperでXPathを使って特定の要素を取り出し方はわかったのですが
たとえば

<br>
<br>
<b>大きく</b>
<br>
<br>
普通に
<br>
<br>

このようなIDやクラスを使われていない場合に「普通に」部分だけ取り出す指定の仕方はどうやるのでしょうか?

具体的な例があれば解説は不要です。

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2012/04/06 07:50:28
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Cherenkov No.2

回答回数1504ベストアンサー獲得回数493

ポイント100pt
/html/body/text()[contains(.,"normal")]

http://jsfiddle.net/cherenkov/pFsME/1/

jsfiddleで動作確認するために/html/body/とかいていますが、適当に//text()から始めたほうが汎用的ですね。一応。

contains(str1, str2)
str1の.はコンテキストノード自身。

参考:「ツイート」を「ツイート(笑)」に置換するブックマークレット - IT戦記




追記:
コメントに書いたもの
https://gist.github.com/2314469

参考:よしいずの雑記帳  Web::Scraperを使ったPerlプログラムの例

id:robopit

こちらがサンプルになりますhttps://gist.github.com/84958dbb49ecb3c9ebb9

//td/text()[not(normalize-space(.)="")]

で出来ましたありがとうございました

2012/04/06 07:38:31

その他の回答1件)

id:Lhankor_Mhy No.1

回答回数814ベストアンサー獲得回数232

ポイント20pt

'/html/body/text()'
http://jsfiddle.net/AZn6W/

id:Cherenkov No.2

回答回数1504ベストアンサー獲得回数493ここでベストアンサー

ポイント100pt
/html/body/text()[contains(.,"normal")]

http://jsfiddle.net/cherenkov/pFsME/1/

jsfiddleで動作確認するために/html/body/とかいていますが、適当に//text()から始めたほうが汎用的ですね。一応。

contains(str1, str2)
str1の.はコンテキストノード自身。

参考:「ツイート」を「ツイート(笑)」に置換するブックマークレット - IT戦記




追記:
コメントに書いたもの
https://gist.github.com/2314469

参考:よしいずの雑記帳  Web::Scraperを使ったPerlプログラムの例

id:robopit

こちらがサンプルになりますhttps://gist.github.com/84958dbb49ecb3c9ebb9

//td/text()[not(normalize-space(.)="")]

で出来ましたありがとうございました

2012/04/06 07:38:31
  • id:robopit
    回答ありがとうございます。
    ただ、やってみたのですができない状態です。

    fontで囲まれた要素を引っ張ってきてしまい
    fontと同じ階層にあるテキストはでてきません

    親要素がtr[2]と指定してあるのですがなにか関係があるのでしょうか?
    trを取り外してtext()だけにしてみたのですがこれもまたなぜかfont
    の部分だけしか引っ張りませんでした
  • id:Cherenkov
    HTMLとコードの提示が必要かと
  • id:Cherenkov
    .//font/text()[contains(.,"てすと2222")]
  • id:Cherenkov
    とか
    var r = document.evaluate('.//text()', document, null, 7, null);
    for (var i=0, l=r.snapshotLength; i<l; i++) {
    if (/てすと2222/.test(r.snapshotItem(i).textContent)) {
    alert(r.snapshotItem(i).textContent)
    }
    }
  • id:robopit
    ピンポイントで指定しないと取得できないってことでしょうか?
  • id:Lhankor_Mhy
    そのソースの構造で書くならたぶん
    //body/font/text()
  • id:Lhankor_Mhy
    ↑そのソースがbody直下にあると仮定してます。違うなら変更してください。
  • id:Cherenkov
    ピンポイントじゃなかったら、どのように相対的に指定したいのでしょうか。
  • id:Lhankor_Mhy
    あ、回答に追記があったのね……
  • id:robopit
    返答遅れてすいません
    こういう構成のものがたくさんある場合


    /html/body//tr/td[2]/br[5]みたいな感じで取り出せればな
    考えていたのですが無理でしょうか
  • id:Cherenkov
    ケースバイケースなのでソースを提示してもらえれば…
  • id:Cherenkov
    //td/text()[not(normalize-space(.)="")]
    でどうですか。tableの情報追加で補強したほうがいいかもしれないけど。
    https://gist.github.com/2314469
  • id:Cherenkov
    /html/body/table//tr/td[2]/text()[not(normalize-space(.)="")]
  • id:robopit
    ありがとうございます!
    できました。
    なぜできたかは自分でもしれべてみたいと思います。
    ありがとうございました。
  • id:robopit
    こちらがサンプルになりますhttps://gist.github.com/84958dbb49ecb3c9ebb9

    //td/text()[not(normalize-space(.)="")]

    でかいけつしました

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません