как я могу преобразовать таблицу html в csv?

<p>как преобразовать содержимое таблицы html (<code><table></code>) в формат csv? есть ли библиотека или программа linux, которая делает это? это похоже на копирование таблиц в internet explorer и вставку их в excel.</p>

<p>этот метод на самом деле не является библиотекой or программы, но для специальных преобразований вы можете </p><ul> <li>поместите html для таблицы в файл <em>text</em> с именем<strong>-thing.xls </strong></li> <li>откройте его с помощью электронной таблицы</li> <li>сохранить его как csv.</li> </ul><p>я знаю, что это работает с excel, и я думаю, что я сделал это с электронной таблицей openoffice.</p><p>но вы, вероятно, предпочли бы сценарий perl или ruby ...</p>

<p>извините за возрождение древнего потока, но недавно я хотел это сделать, но я хотел, чтобы это сделал 100% переносимый скрипт bash. итак, вот мое решение с использованием только grep и sed.</p><p>нижеследующее было сделано очень быстро, поэтому его можно сделать более элегантным, но я только начинаю с sed/awk и т.д.</p><pre><code>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, но вы также можете легко использовать источник таблицы из другого источника.вот объяснение:получить содержимое url с помощью curl, сбросить stderr в ноль (без индикатора выполнения)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 'nr' ,.заменить  новой строкой| sed 's/</tr[^>]>/n/ig' ,.удалить теги table и tr| sed 's/</?(table|tr)[^>]>//ig' ,.удалить ^, ^, $</code>, <code></th>$| sed 's/^<t[dh][^>]>|</?t[dh][^>]>$//ig' </code></pre><p>,.</p><p>заменить <code></td><td></code> запятой</p><pre><code>| sed 's/<\/t[dh][^>]*><t[dh][^>]*>/,/ig' </code></pre><p>,.</p><p>обратите внимание, что если в какой-либо из ячеек таблицы содержатся запятые, вам может понадобиться сначала их избежать или использовать другой разделитель.</p><p>надеюсь, это поможет кому-то!</p>

<p>вот скрипт на ruby, в котором используется нокогири - <a href="http://nokogiri.rubyforge.org/nokogiri/">http://nokogiri.rubyforge.org/nokogiri/</a> </p><pre><code>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 </code></pre><p>работал для моего основного теста.</p>

<p>вот небольшая программа на python, которую я написал для выполнения этой задачи. он был написан за пару минут, так что, вероятно, его можно сделать лучше. не уверен, как он будет обрабатывать вложенные таблицы (возможно, это будет плохо) или несколько таблиц (возможно, они будут отображаться одна за другой). он не обрабатывает <code>colspan</code> или <code>rowspan</code>. наслаждайтесь.</p><pre><code>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()) </code></pre>

<p>я не уверен, есть ли готовая библиотека для этого, но если вы хотите испачкать руки небольшим perl, вы, вероятно, могли бы что-то сделать с <a href="http://search.cpan.org/perldoc/text::csv"><code>text::csv</code></a> и <a href="http://search.cpan.org/perldoc/html::parser"><code>html::parser</code></a> .</p>

<p>в perl вы можете использовать модуль <a href="http://search.cpan.org/perldoc/html::tableextract"><code>html::tableextract</code></a> для извлечения данных из таблицы, а затем использовать <a href="http://search.cpan.org/perldoc/text::csv\_xs"><code>text::csv\_xs</code></a> для создания файла csv или <a href="http://search.cpan.org/perldoc/spreadsheet::writeexcel"><code>spreadsheet::writeexcel</code></a> для создания файла excel.</p>

<p>предполагая, что вы разработали html-страницу, содержащую таблицу, я бы порекомендовал это решение. работал как шарм для меня.</p><pre><code>$(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(); }); }); </code></pre><p>предоставлено: <a href="http://www.kubilayerdogan.net/?p=218">http://www.kubilayerdogan.net/?p=218</a> </p><p>вы можете редактировать формат файла в .csv здесь a.download = 'exported\_table\_' + postfix + '.csv';</p>

<p>просто добавьте к этим ответам (как я недавно пытался сделать то же самое) - если<strong> таблицы google </strong>ваша программа выбора таблиц. просто сделайте эти две вещи.</p><p><strong> 1. </strong>удалите все из вашего html-файла вокруг<strong> тегов открытия/закрытия таблицы </strong>и сохраните его как другой html-файл.</p><p><strong> 2. </strong>импортируйте этот html-файл непосредственно в электронные таблицы google, и ваша информация будет прекрасно импортирована <em>(главный совет: если вы использовали встроенные стили в своей таблице, они также будут импортированы!)</em></p><p>сэкономила мне кучу времени и выяснила разные конверсии. </p>

<p>основано на <a href="https://stackoverflow.com/questions/1403087/how-can-i-convert-an-html-table-to-csv/1403325#1403325">ответ аудио-датчика</a> , но упрощено с помощью встроенной библиотеки csv</p><pre><code>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 </code></pre><p>я действительно задавался вопросом, есть ли какой-нибудь способ взять nodeset nokogiri (<code>row.xpath('td')</code>) и записать это как массив в файл csv за один шаг. но я мог понять, что делать это можно, перебирая каждую ячейку и создавая временный массив содержимого каждой ячейки.</p>

<p>вот пример использования <a href="http://search.cpan.org/dist/pquery/">pquery</a> и <a href="http://search.cpan.org/dist/spreadsheet-writeexcel/">spreadsheet :: writeexcel</a> :</p><pre><code>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; </code></pre><p>в примере просто извлекаются все найденные теги <em>tr</em> в файл excel. вы можете легко настроить его, чтобы подобрать определенный <em>table</em> или даже вызвать новый файл excel для тега <em>table</em>.</p><p>дальнейшие вещи для рассмотрения:</p><ul> <li>вы можете выбрать теги <em>td</em> для создания заголовков excel.</li> <li>и у вас могут быть проблемы с rowspan и colspan. </li> </ul><p>чтобы узнать, используется ли rowspan или colspan, вы можете:</p><pre><code>pquery( $data )->find( 'td' )->each( sub{ my $number\_of\_cols\_spanned = $\_->getattribute( 'colspan' ); }); </code></pre>

<p>вот несколько вариантов</p><p> <a href="http://groups.google.com/group/ruby-talk-google/browse\_thread/thread/cfae0aa4b14e5560?hl=nn">http://groups.google.com/group/ruby-talk-google/browse\_thread/thread/cfae0aa4b14e5560?hl=nn</a> </p><p> <a href="http://ouseful.wordpress.com/2008/10/14/data-scraping-wikipedia-with-google-spreadsheets/">http://ouseful.wordpress.com/2008/10/14/data-scraping-wikipedia-with-google-spreadsheets/</a> </p><p> <a href="https://stackoverflow.com/questions/259091/how-can-i-scrape-an-html-table-to-csv">как я могу очистить таблицу html в csv?</a> </p><p> <a href="https://addons.mozilla.org/en-us/firefox/addon/1852">https://addons.mozilla.org/en-us/firefox/addon/1852</a> </p>

<p>openoffice.org может просматривать таблицы html. просто используйте команду open для файла html или выберите и скопируйте таблицу в браузере, а затем вставьте special в openoffice.org. он запросит у вас тип файла, один из которых должен быть html. выберите это и вуаля!</p>

<p>это очень старая тема, но, возможно, кто-то, похожий на меня, натолкнется на нее . я сделал несколько дополнений для скрипта <a href="https://stackoverflow.com/users/41060/audiodude">audiodude</a> , чтобы прочитать html из файла, вместо этого добавив его в код, и другой параметр, который управляет печатью строк заголовка.</p><p>скрипт должен быть запущен так</p><pre><code>ruby <script\_name> <file\_name> [<print\_headers>] </code></pre><p>код:</p><pre><code>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 </code></pre>

<p>это основано на <a href="https://stackoverflow.com/questions/1403087/how-can-i-convert-an-html-table-to-csv/7318896#7318896">ответе atomicules</a> но более кратко и также обрабатывает ячейки <code>th</code> (заголовок) и ячейки <code>td</code>. я также добавил метод <code>strip</code>, чтобы избавиться от лишних пробелов.</p><pre><code>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 </code></pre><p>обтекание кода внутри блока csv гарантирует, что файл будет закрыт должным образом.</p><hr><p>если вы просто хотите текст и не нужно записывать его в файл, вы можете использовать это:</p><pre><code>doc.xpath('//table//tr').inject('') do |result, row| result << row.xpath('th|td').map {|cell| cell.text.strip}.to\_csv end </code></pre>