将给定 URL 中的 HTML 表格抓取到 CSV
Posted
技术标签:
【中文标题】将给定 URL 中的 HTML 表格抓取到 CSV【英文标题】:Scrape HTML tables from a given URL into CSV 【发布时间】:2011-02-06 08:57:20 【问题描述】:我寻求一种可以像这样在命令行上运行的工具:
tablescrape 'http://someURL.foo.com' [n]
如果未指定n
并且页面上有多个 html 表格,则应将它们(标题行、总行数)汇总在一个编号列表中。
如果指定了n
或者只有一个表,它应该解析该表并将其作为 CSV 或 TSV 输出到标准输出。
潜在的附加功能:
实际上,您可以在一个表中解析一个表,但出于我的目的——从***页面等获取数据——这太过分了。 asciify 任何 unicode 的选项。 应用任意正则表达式替换以修复已解析表中的怪异之处的选项。你会用什么来拼凑这样的东西? Perl 模块HTML::TableExtract 可能是一个很好的起点,甚至可以处理嵌套表的情况。 这也可能是一个很短的 Python 脚本,带有BeautifulSoup。 YQL 会是一个好的起点吗? 或者,理想情况下,您是否写过类似的东西并有指向它的指针? (我肯定不是第一个需要这个的人。)
相关问题:
How can I scrape an HTML table to CSV? How can I convert an HTML table to CSV? Options for HTML scraping?【问题讨论】:
抱歉@dreeves,但 Stack Overflow 不是“免费程序员出租”服务。 但是问题在哪里? 如果您想重新表述问题,请编辑问题。 (完成;谢谢。请注意,如果存在这样的工具,我会问这个问题。如果没有,我会自己编写并在这里分享) 【参考方案1】:使用TestPlan 我制作了一个粗略的脚本。鉴于网络表格的复杂性,它可能需要针对所有网站进行定制。
第一个脚本列出了页面上的表格:
# A simple table scraping example. It lists the tables on a page
#
# Cmds.Site = the URL to scan
default %Cmds.Site% http://en.wikipedia.org/wiki/List_of_Olympic_records_in_athletics
GotoURL %Cmds.Site%
set %Count% 1
foreach %Table% in (response //table)
Notice Table #%Count%
# find a suitable name, look back for a header
set %Check% ./preceding::*[name()='h1' or name()='h2' or name()='h3'][1]
if checkIn %Table% %Check%
Notice (selectIn %Table% %Check%)
end
set %Count% as binOp %Count% + 1
end
然后第二个脚本将一个表的数据提取到一个 CSV 文件中。
# Generic extract of contents of a table in a webpage
# Use list_tables to get the list of table and indexes
#
# Cmds.Site = the URL to scan
# Cmds.Index = Table index to scan
default %Cmds.Site% http://en.wikipedia.org/wiki/List_of_Olympic_records_in_athletics
default %Cmds.Index% 2
GotoURL %Cmds.Site%
set %Headers% //table[%Cmds.Index%]/tbody/tr[1]
set %Rows% //table[%Cmds.Index%]/tbody/tr[position()>1]
# Get an cleanup the header fields
set %Fields% withvector
end
foreach %Header% in (response %Headers%/*)
putin %Fields% (trim %Header%)
end
Notice %Fields%
# Create an output CSV
call unit.file.CreateDataFile with
%Name% %This:Dir%/extract_table.csv
%Format% csv
%Fields% %Fields%
end
set %DataFile% %Return:Value%
# Now extract each row
foreach %Row% in (response %Rows%)
set %Record% withvector
end
foreach %Cell% in (selectIn %Row% ./td)
putin %Record% (trim %Cell%)
end
call unit.file.WriteDataFile with
%DataFile% %DataFile%
%Record% %Record%
end
end
call unit.file.CloseDataFile with
%DataFile% %DataFile%
end
我的 CSV 文件如下所示。请注意,***在每个单元格中都有提取信息。有很多方法可以摆脱它,但不是通用的。
Shot put,22.47 m,"Timmermann, UlfUlf Timmermann",East Germany (GDR),1988 1988 Seoul,"01988-09-23 September 23, 1988",[25]
Discus throw,69.89 m,"Alekna, VirgilijusVirgilijus Alekna",Lithuania (LTU),2004 2004 Athens,"02004-08-23 August 23, 2004",[26]
Hammer throw,84.80 m,"Litvinov, SergeySergey Litvinov",Soviet Union (URS),1988 1988 Seoul,"01988-09-26 September 26, 1988",[27]
Javelin throw,90.57 m,"Thorkildsen, AndreasAndreas Thorkildsen",Norway (NOR),2008 2008 Beijing,"02008-08-23 August 23, 2008",[28]
【讨论】:
谢谢!这看起来不错。在我写的版本中,我最终放入了特殊情况以删除您所谓的***的提取信息。【参考方案2】:这是我的第一次尝试:
http://yootles.com/outbox/tablescrape.py
它需要更多的工作,比如更好的 asciifying,但它是可用的。比如你把它指向这个list of Olympic records:
./tablescrape http://en.wikipedia.org/wiki/List_of_Olympic_records_in_athletics
它告诉您有 8 个表可用,很明显,第 2 和第 3 个(男性和女性记录)是您想要的:
1: [ 1 cols, 1 rows] Contents 1 Men's rec
2: [ 7 cols, 25 rows] Event | Record | Name | Nation | Games | Date | Ref
3: [ 7 cols, 24 rows] Event | Record | Name | Nation | Games | Date | Ref
[...]
然后如果你再次运行它,要求第二张桌子,
./tablescrape http://en.wikipedia.org/wiki/List_of_Olympic_records_in_athletics 2
你得到一个合理的明文数据表:
100 metres | 9.69 | Usain Bolt | Jamaica (JAM) | 2008 Beijing | August 16, 2008 | [ 8 ]
200 metres | 19.30 | Usain Bolt | Jamaica (JAM) | 2008 Beijing | August 20, 2008 | [ 8 ]
400 metres | 43.49 | Michael Johnson | United States (USA) | 1996 Atlanta | July 29, 1996 | [ 9 ]
800 metres | 1:42.58 | Vebjørn Rodal | Norway (NOR) | 1996 Atlanta | July 31, 1996 | [ 10 ]
1,500 metres | 3:32.07 | Noah Ngeny | Kenya (KEN) | 2000 Sydney | September 29, 2000 | [ 11 ]
5,000 metres | 12:57.82 | Kenenisa Bekele | Ethiopia (ETH) | 2008 Beijing | August 23, 2008 | [ 12 ]
10,000 metres | 27:01.17 | Kenenisa Bekele | Ethiopia (ETH) | 2008 Beijing | August 17, 2008 | [ 13 ]
Marathon | 2:06:32 | Samuel Wanjiru | Kenya (KEN) | 2008 Beijing | August 24, 2008 | [ 14 ]
[...]
【讨论】:
以上是关于将给定 URL 中的 HTML 表格抓取到 CSV的主要内容,如果未能解决你的问题,请参考以下文章
抓取:将存储为图片的数据添加到 python 3.5 中的 CSV 文件