[ruby-list:46408] html→csv変換|tableのセル結合に対応したものは?

Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[ruby-list:46408] html→csv変換|tableのセル結合に対応したものは?

YOSHIIZUMI
 吉泉といいます。

 html→csv変換で、tableのセル結合に対応したrubyライブラリは、既にあるでしょう
か?
 例えば、rowspanを使った次のようなhtmlのtableがあるとします。

----
<table>
<tr>
<td rowspan="3">垂直方向の結合</td>
<td>データセル1</td>
</tr>

<tr>
<td>データセル2</td>
</tr>

<tr>
<td>データセル3</td>
</tr>
</table>
----

上を変換した結果として、下のようなcsvを得られる、そんな変換ライブラリがあればと
思うのですが。

----
垂直方向の結合,データセル1
,データセル2
,データセル3
----

 既存のものがなければ自作するしかないかなと思いつつ、実際のデータは結構複雑な
ので、簡単に済ませられる方法があればと思っています。
 Webであれこれ検索してみましたが、よく分かりませんでした。
 アドバイスがありましたら、よろしくお願いします。


Reply | Threaded
Open this post in threaded view
|

[ruby-list:46862] Re: html→csv変換|tableのセル結合に対応したものは?

YOSHIIZUMI
 吉泉といいます。
 昨年9月、htmlのtable(セル結合あり)をcsvに変換する方法について質問さ
せていただきましたが、関連して、今更の自己resです。

 table部分をrubyの配列に変換するメソッドを書きました。
    table_str = '<table>  ...  </table>'
    ary = table_to_array(table_str)
のようにすると、2次元配列 ary を得ます。配列の各要素は、htmlタグを除
去したテキストです。
 テキストでなく、タグ付きの「<td> ... </td>」を各要素に記録したい時は
    ary = table_to_array(table_str, :HTML)
とします。
 なお、htmlパーサにはhpricotを使っています。

 配列にしてしまえば、あとは csvとか箇条書きふうに変換するのが容易です。
 私は視覚障害者で画面が見えず tableの把握が苦手なので、こんな発想をし
がちです。でも、rubyなどで発想を具体化できるのは うれしいことです。

 このメソッドの応用例として、yahooのテレビ・ラジオ番組表を箇条書きふ
うのテキストファイルの形で書き出すスクリプト「tv_yahoo.rb」を作ってみ
ました。以下が掲載場所です。
http://cup.sakura.ne.jp/hiki/hiki.cgi?prog01_guide

 スクリプト内には、おまけで、MS-Windows上でhtmlドキュメントを取得する
ための class Mshttp を入れてあります。
 Msxml2.xmlhttp を利用した単純・素朴なものです。
    mshttp = Mshttp.new(:WIN32)
    html_doc = mshttp.web_open('http://www.hoge.com/q.cgi?a=1&b=2')
などのようにすると、htmlドキュメントをバイナリで得られます(改行は
"\r\n" になる。zip圧縮ファイルなども取得可能)。
 *.pacによる設定の場合を含め proxyがどうなっているかを気にせずに使え
ます。InternetExploreが動く環境であれば、このclassも動くと思います。

 なお、:WIN32 を指定せずに単に Mshttp.new と初期化した場合は open-uri
の openメソッドでwebを取得するようになります。
 その場合、win32oleを用いないので linux などでも動くと思います。
 ただし、proxyへの対応は、別途 行う必要が出てきます。

 よかったら覗いてみて下さい。


Reply | Threaded
Open this post in threaded view
|

[ruby-list:46867] Re: html→csv変換|tableのセル結合に対応したものは?

Shin-ichiro HARA
原です。

>  吉泉といいます。
>  昨年9月、htmlのtable(セル結合あり)をcsvに変換する方法について質問さ
> せていただきましたが、関連して、今更の自己resです。
>
>  table部分をrubyの配列に変換するメソッドを書きました。
>      table_str = '<table>   ...</table>'
>      ary = table_to_array(table_str)
> のようにすると、2次元配列 ary を得ます。配列の各要素は、htmlタグを除
> 去したテキストです。
>  テキストでなく、タグ付きの「<td>  ...</td>」を各要素に記録したい時は
>      ary = table_to_array(table_str, :HTML)
> とします。
>  なお、htmlパーサにはhpricotを使っています。

たまたま私も html のテーブルを読まねばならない仕事があったので、興味
を持ちました。この問題を考えて見たのですが結構むずかしいですね。私な
りの答えを書きます。

  def table_to_array2(tbl_str, data_type=:TEXT)
    tbl = Hpricot(tbl_str)
    trs = tbl.search("tr")
    aa = []
    span = {}
    trs.each_with_index{|e, row_n|
      a = []
      col_n = 0
      e.search("td").each{|e2|
        while span[[row_n, col_n]]
          a.push("")
          col_n += 1
        end
        data = data_type == :TEXT ? e2.inner_text : e2.to_html
        a.push(data)

        cspan = 1
        if e2.attributes['colspan'] =~ /(\d+)/
          cspan = $1.to_i
        end
        rspan = 1
        if e2.attributes['rowspan'] =~ /(\d+)/
          rspan = $1.to_i
        end
        for r in row_n...(row_n+rspan)
          for c in col_n...(col_n+cspan)
            span[[r, c]] = true
          end
        end

        col_n += 1
      }
      aa.push(a)
    }
    return aa
  end

span で省かれた要素を "" で表すという仕様は若干問題あるかもしれませんね。
もともとのデータが空である場合と区別がつかないので。

Reply | Threaded
Open this post in threaded view
|

[ruby-list:46868] Re: html→csv変換|tableのセル結合に対応したものは?

YOSHIIZUMI
 吉泉です。
 原さん、RESありがとうございます。

In reply to Shin-ichiro HARA <[hidden email]>'s message:
| span で省かれた要素を "" で表すという仕様は若干問題あるかもしれませんね。
| もともとのデータが空である場合と区別がつかないので。

 上記、確かにそうですね。
 また、全体的に原さんの table_to_array2 の方が、スマートにすっきりし
ている感じです。
 each_with_index の使い方、Hashの要素に座標を示す [1,1] などを持って
くるやり方、勉強になります。
 当然ながら、tv_yahoo.rbの中に組み入れて実行したところ、ちゃんと番組
表が得られました。
 使わせていただきます。


Reply | Threaded
Open this post in threaded view
|

[ruby-list:46869] Re: html→csv変換|tableのセル結合に対応したものは?

Shin-ichiro HARA
原です。

>  吉泉です。
>  原さん、RESありがとうございます。
>
> In reply to Shin-ichiro HARA<[hidden email]>'s message:
> | span で省かれた要素を "" で表すという仕様は若干問題あるかもしれませんね。
> | もともとのデータが空である場合と区別がつかないので。
>
>  上記、確かにそうですね。

内部的には(配列の段階では)""でなく、文字列クラスでないオブジェクト
で保持したらいいと思いますが、CSVに変換したら、nilを""として表現する
ぐらいしか思いつきませんね。

>  また、全体的に原さんの table_to_array2 の方が、スマートにすっきりし
> ている感じです。
>  each_with_index の使い方、Hashの要素に座標を示す [1,1] などを持って
> くるやり方、勉強になります。

私こそ勉強になりました。今回はじめて hpricot を使ってみたのです。
each_with_index は、使えるかもしれないので使ってみたら使えた、という
ところです。search が「再帰的」に使えることも。

ところで、文章は読み上げソフトウェアを使って読むのでしょうか。プログ
ラミング言語を読むのに適した読み上げソフトウェアってあります?インデ
ントは無視されていまうでしょうか。だとしたら Python などは困りますね。

Reply | Threaded
Open this post in threaded view
|

[ruby-list:46870] Re: html→csv変換|tableのセル結合に対応したものは?

YOSHIIZUMI
 吉泉です。
 余談ネタですみませんが少々。

In reply to Shin-ichiro HARA <[hidden email]>'s message:
| ところで、文章は読み上げソフトウェアを使って読むのでしょうか。プログ
| ラミング言語を読むのに適した読み上げソフトウェアってあります?インデ
| ントは無視されていまうでしょうか。だとしたら Python などは困りますね。

 画面表示を読み上げるソフト(スクリーンリーダーといいます。)を使ってい
ます。
 連続読みさせると、インデントを把握することはできません。
 ただ、カーソルで1文字づつ(あるいは単語単位など)辿る方法であれば、イ
ンデントをはじめ細かな情報を確認できます。
 この連続読みと辿り読みを適当に組み合わせることで、なんとかスクリプト
を書けます。サンプルも理解することができます。
 晴眼者の人に比べると時間はかかるかもしれませんが、「ああでもない・こ
うでもない」と ぐだぐだやってるのが楽しいです。

 Pythonは、ほとんど使ってませんが、使えないことはないと思います。
 私は古いタイプなので、sed / awk / perl が大好きです。もちろん ruby
も大ファンです。
 今時 awk を使う人はあまりいそうにないですが、ちょっとしたデータ処理
には今でも awk を多用してます。
 余談ネタ 失礼しました。


Reply | Threaded
Open this post in threaded view
|

[ruby-list:46872] Re: html→csv変換|tableのセル結合に対応したものは?

Shin-ichiro HARA
原です。

>  吉泉です。

>  画面表示を読み上げるソフト(スクリーンリーダーといいます。)を使ってい
> ます。
>  連続読みさせると、インデントを把握することはできません。
>  ただ、カーソルで1文字づつ(あるいは単語単位など)辿る方法であれば、イ
> ンデントをはじめ細かな情報を確認できます。
>  この連続読みと辿り読みを適当に組み合わせることで、なんとかスクリプト
> を書けます。サンプルも理解することができます。

なるほど一文字づつという読み方もするんですね。

私は「なんにせよ一目でパッっとわかるのが一番いい」とか普段言いがち
なのだけど、それとは異質な世界もあるんだなあ。

>  今時 awk を使う人はあまりいそうにないですが、ちょっとしたデータ処理
> には今でも awk を多用してます。

私も awk->perl->rubyというコースですが、awkもperlも全く使わなくなってし
まいました。