HTMLテーブルのコンテンツ(<table>
)CSV形式に?これを行うライブラリまたはLinuxプログラムはありますか?これは、Internet Explorerでテーブルをコピーし、それらをExcelに貼り付けることに似ています。
このメソッドは、実際にはライブラリORプログラムではありませんが、アドホック変換の場合は、
これがExcelで機能することは知っていますし、OpenOfficeスプレッドシートでこれをやったと思います。
しかし、おそらくPerlまたはRuby script ...
古代のスレッドを復活させてすみませんが、最近これをやりたかったのですが、100%ポータブルなbashスクリプトでそれを実現したかったのです。そこで、grepとsedのみを使用したソリューションを紹介します。
以下は非常に早く打ち消されたので、もっとエレガントにすることができましたが、sed/awkなどで本当に始めたばかりです...
curl "http://www.webpagewithtableinit.com/" 2>/dev/null | grep -i -e '</\?TABLE\|</\?TD\|</\?TR\|</\?TH' | sed 's/^[\ \t]*//g' | tr -d '\n' | sed 's/<\/TR[^>]*>/\n/Ig' | sed 's/<\/\?\(TABLE\|TR\)[^>]*>//Ig' | sed 's/^<T[DH][^>]*>\|<\/\?T[DH][^>]*>$//Ig' | sed 's/<\/T[DH][^>]*><T[DH][^>]*>/,/Ig'
ご覧のとおり、curlを使用してページソースを取得しましたが、テーブルソースを他の場所から簡単に取り込むことができます。
説明は次のとおりです。
CURLを使用してURLのコンテンツを取得し、stderrをnullにダンプします(進行状況メーターなし)
curl "http://www.webpagewithtableinit.com/" 2>/dev/null
。
テーブル要素のみが必要です(TABLE、TR、TH、TDタグのある行のみを返します)
| grep -i -e '</\?TABLE\|</\?TD\|</\?TR\|</\?TH'
。
行の先頭にある空白を削除します。
| sed 's/^[\ \t]*//g'
。
改行を削除する
| tr -d '\n\r'
。
</TR>
を改行に置き換えます
| sed 's/<\/TR[^>]*>/\n/Ig'
。
TABLEおよびTRタグを削除する
| sed 's/<\/\?\(TABLE\|TR\)[^>]*>//Ig'
。
^<TD>
、^<TH>
、</TD>$
、</TH>$
を削除します
| sed 's/^<T[DH][^>]*>\|<\/\?T[DH][^>]*>$//Ig'
。
</TD><TD>
をコンマに置き換えます
| sed 's/<\/T[DH][^>]*><T[DH][^>]*>/,/Ig'
。
テーブルセルのいずれかにカンマが含まれている場合は、最初にエスケープするか、別の区切り文字を使用する必要がある場合があります。
これが誰かを助けることを願っています!
Ruby nokogiriを使用するスクリプト- http://nokogiri.rubyforge.org/nokogiri/
require 'nokogiri'
doc = Nokogiri::HTML(table_string)
doc.xpath('//table//tr').each do |row|
row.xpath('td').each do |cell|
print '"', cell.text.gsub("\n", ' ').gsub('"', '\"').gsub(/(\s){2,}/m, '\1'), "\", "
end
print "\n"
end
私の基本的なテストケースで働いた。
ここに短いPythonこのタスクを完了するために書いたプログラムがあります。数分で書かれたので、おそらくより良くすることができます。 「悪いことをする」または複数のテーブル(たぶん次々に表示されます)。colspan
またはrowspan
を処理しません。
from HTMLParser import HTMLParser
import sys
import re
class HTMLTableParser(HTMLParser):
def __init__(self, row_delim="\n", cell_delim="\t"):
HTMLParser.__init__(self)
self.despace_re = re.compile(r'\s+')
self.data_interrupt = False
self.first_row = True
self.first_cell = True
self.in_cell = False
self.row_delim = row_delim
self.cell_delim = cell_delim
def handle_starttag(self, tag, attrs):
self.data_interrupt = True
if tag == "table":
self.first_row = True
self.first_cell = True
Elif tag == "tr":
if not self.first_row:
sys.stdout.write(self.row_delim)
self.first_row = False
self.first_cell = True
self.data_interrupt = False
Elif tag == "td" or tag == "th":
if not self.first_cell:
sys.stdout.write(self.cell_delim)
self.first_cell = False
self.data_interrupt = False
self.in_cell = True
def handle_endtag(self, tag):
self.data_interrupt = True
if tag == "td" or tag == "th":
self.in_cell = False
def handle_data(self, data):
if self.in_cell:
#if self.data_interrupt:
# sys.stdout.write(" ")
sys.stdout.write(self.despace_re.sub(' ', data).strip())
self.data_interrupt = False
parser = HTMLTableParser()
parser.feed(sys.stdin.read())
このために事前に作成されたライブラリがあるかどうかはわかりませんが、少しのPerlで手を汚したい場合は、おそらく Text::CSV
および HTML::Parser
。
これらの回答に追加するだけです(最近同様のことを試みています)-Googleスプレッドシートが選択したスプレッドシートプログラムである場合。これら2つのことを行うだけです。
1。 htmlファイルからテーブル開始/終了タグの周りのすべてを取り除き、別のhtmlファイルとして再保存します。
2。 htmlファイルを直接Googleスプレッドシートにインポートすると、情報がきれいにインポートされます(トップヒント:テーブルでインラインスタイルを使用した場合、同様にインポートされます!)
時間を節約して、さまざまなコンバージョンを見つけました。
Perlでは、 HTML::TableExtract
テーブルからデータを抽出してから Text::CSV_XS
CSVファイルを作成するか、 Spreadsheet::WriteExcel
Excelファイルを作成します。
テーブルを含むhtmlページを設計したと仮定すると、このソリューションをお勧めします。私にとって魅力のように働いた。
$(document).ready(function() {
$("#btnExport").click(function(e) {
//getting values of current time for generating the file name
var dt = new Date();
var day = dt.getDate();
var month = dt.getMonth() + 1;
var year = dt.getFullYear();
var hour = dt.getHours();
var mins = dt.getMinutes();
var postfix = day + "." + month + "." + year + "_" + hour + "." + mins;
//creating a temporary HTML link element (they support setting file names)
var a = document.createElement('a');
//getting data from our div that contains the HTML table
var data_type = 'data:application/vnd.ms-Excel';
var table_div = document.getElementById('dvData');
var table_html = table_div.outerHTML.replace(/ /g, '%20');
a.href = data_type + ', ' + table_html;
//setting the file name
a.download = 'exported_table_' + postfix + '.xls';
//triggering the function
a.click();
//just in case, prevent default behaviour
e.preventDefault();
});
});
礼儀: http://www.kubilayerdogan.net/?p=218
ここでファイル形式を.csvに編集できますa.download = 'exported_table_' + postfix + '.csv';
ここに外部ライブラリのないシンプルなソリューション:
https://www.codexworld.com/export-html-table-data-to-csv-using-javascript/
問題なく動作します
audiodude's answer に基づきますが、組み込みのCSVライブラリを使用して簡略化されています
_require 'nokogiri'
require 'csv'
doc = Nokogiri::HTML(table_string)
csv = CSV.open("output.csv", 'w')
doc.xpath('//table//tr').each do |row|
tarray = [] #temporary array
row.xpath('td').each do |cell|
tarray << cell.text #Build array of that row of data.
end
csv << tarray #Write that row out to csv file
end
csv.close
_
Nokogiri NodeSet(row.xpath('td')
)を取得し、これをcsvファイルへの配列として1ステップで書き込む方法があるかどうか疑問に思いました。しかし、各セルを反復処理し、各セルのコンテンツの一時的な配列を構築することによって、それを行うことしか理解できませんでした。
これは非常に古いスレッドですが、私のような誰かがそれにぶつかる可能性があります。 audiodude のスクリプトに追加して、ファイルからHTMLを読み取る代わりに、コードに追加し、ヘッダー行の印刷を制御する別のパラメーターを追加しました。
スクリプトはそのように実行する必要があります
Ruby <script_name> <file_name> [<print_headers>]
コードは次のとおりです。
require 'nokogiri'
print_header_lines = ARGV[1]
File.open(ARGV[0]) do |f|
table_string=f
doc = Nokogiri::HTML(table_string)
doc.xpath('//table//tr').each do |row|
if print_header_lines
row.xpath('th').each do |cell|
print '"', cell.text.gsub("\n", ' ').gsub('"', '\"').gsub(/(\s){2,}/m, '\1'), "\", "
end
end
row.xpath('td').each do |cell|
print '"', cell.text.gsub("\n", ' ').gsub('"', '\"').gsub(/(\s){2,}/m, '\1'), "\", "
end
print "\n"
end
end
OpenOffice.orgはHTMLテーブルを表示できます。 HTMLファイルでopenコマンドを使用するか、ブラウザでテーブルを選択してコピーしてから、OpenOffice.orgで形式を選択して貼り付けます。ファイルタイプを照会しますが、その1つはHTMLである必要があります。それを選択して出来上がり!
これは atomicules 'answer に基づいていますが、より簡潔で、th
(ヘッダー)セルとtd
セルも処理します。また、余分な空白を取り除くためにstrip
メソッドを追加しました。
CSV.open("output.csv", 'w') do |csv|
doc.xpath('//table//tr').each do |row|
csv << row.xpath('th|td').map {|cell| cell.text.strip}
end
end
CSVブロック内にコードをラップすると、ファイルが適切に閉じられます。
テキストだけが必要で、ファイルに書き込む必要がない場合は、これを使用できます。
doc.xpath('//table//tr').inject('') do |result, row|
result << row.xpath('th|td').map {|cell| cell.text.strip}.to_csv
end
pQuery および Spreadsheet :: WriteExcel を使用した例を次に示します。
use strict;
use warnings;
use Spreadsheet::WriteExcel;
use pQuery;
my $workbook = Spreadsheet::WriteExcel->new( 'data.xls' );
my $sheet = $workbook->add_worksheet;
my $row = 0;
pQuery( 'http://www.blahblah.site' )->find( 'tr' )->each( sub{
my $col = 0;
pQuery( $_ )->find( 'td' )->each( sub{
$sheet->write( $row, $col++, $_->innerHTML );
});
$row++;
});
$workbook->close;
この例では、検出したすべてのtrタグをExcelファイルに単純に抽出します。特定のtableを選択したり、tableタグ。
さらに考慮すべき事項:
Rowspanまたはcolspanが使用されているかどうかを確認するには:
pQuery( $data )->find( 'td' )->each( sub{
my $number_of_cols_spanned = $_->getAttribute( 'colspan' );
});
Yuvai's answer の更新バージョンは、引用が必要なフィールド(データにコンマを含むフィールド、二重引用符、または複数行にわたるフィールド)を適切に処理します
#!/usr/bin/env python3
from html.parser import HTMLParser
import sys
import re
class HTMLTableParser(HTMLParser):
def __init__(self, row_delim="\n", cell_delim=","):
HTMLParser.__init__(self)
self.despace_re = re.compile("\s+")
self.data_interrupt = False
self.first_row = True
self.first_cell = True
self.in_cell = False
self.row_delim = row_delim
self.cell_delim = cell_delim
self.quote_buffer = False
self.buffer = None
def handle_starttag(self, tag, attrs):
self.data_interrupt = True
if tag == "table":
self.first_row = True
self.first_cell = True
Elif tag == "tr":
if not self.first_row:
sys.stdout.write(self.row_delim)
self.first_row = False
self.first_cell = True
self.data_interrupt = False
Elif tag == "td" or tag == "th":
if not self.first_cell:
sys.stdout.write(self.cell_delim)
self.first_cell = False
self.data_interrupt = False
self.in_cell = True
Elif tag == "br":
self.quote_buffer = True
self.buffer += self.row_delim
def handle_endtag(self, tag):
self.data_interrupt = True
if tag == "td" or tag == "th":
self.in_cell = False
if self.buffer != None:
# Quote if needed...
if self.quote_buffer or self.cell_delim in self.buffer or "\"" in self.buffer:
# Need to quote! First, replace all double-quotes with quad-quotes
self.buffer = self.buffer.replace("\"", "\"\"")
self.buffer = "\"{0}\"".format(self.buffer)
sys.stdout.write(self.buffer)
self.quote_buffer = False
self.buffer = None
def handle_data(self, data):
if self.in_cell:
#if self.data_interrupt:
# sys.stdout.write(" ")
if self.buffer == None:
self.buffer = ""
self.buffer += self.despace_re.sub(" ", data).strip()
self.data_interrupt = False
parser = HTMLTableParser()
parser.feed(sys.stdin.read())
このスクリプトの拡張機能の1つは、異なる行区切り文字(またはプラットフォームに適した区切り文字の自動計算)および異なる列区切り文字の指定のサポートを追加することです。