我正在尝试将此表http://www.datamystic.com/timezone/time_zones.html转换为数组格式,以便我可以随意使用它。最好是PHP,python或JavaScript。
这是一个很多问题,所以我不是在寻找有关这个特定问题的帮助,而是在寻找解决所有类似问题的想法。
BeautifulSoup首先浮现在脑海中。 另一种可能性是在TextMate中复制/粘贴它,然后运行正则表达式。
你有什么建议?
这是我写完的脚本,但正如我所说,我正在寻找更通用的解决方案。
from BeautifulSoup import BeautifulSoup
import urllib2
url = 'http://www.datamystic.com/timezone/time_zones.html';
response = urllib2.urlopen(url)
html = response.read()
soup = BeautifulSoup(html)
tables = soup.findAll("table")
table = tables[1]
rows = table.findAll("tr")
for row in rows:
tds = row.findAll('td')
if(len(tds)==4):
countrycode = tds[1].string
timezone = tds[2].string
if(type(countrycode) is not type(None) and type(timezone) is not type(None)):
print "\'%s\' => \'%s\'," % (countrycode.strip(), timezone.strip())
对我的python代码的改进的评论和建议也欢迎;)
答案 0 :(得分:5)
对于您的一般问题:从lxml.html包中尝试lxml(将其视为类固醇上的stdlibs xml.etree:相同的xml api,但支持html,xpath,xslt等。 ..)
针对您具体案例的简单示例:
from lxml import html
tree = html.parse('http://www.datamystic.com/timezone/time_zones.html')
table = tree.findall('//table')[1]
data = [
[td.text_content().strip() for td in row.findall('td')]
for row in table.findall('tr')
]
这将为您提供一个嵌套列表:每个子列表对应于表中的一行,并包含来自单元格的数据。偷偷插入的广告行尚未过滤掉,但它应该让你顺利。 (顺便说一句:lxml很快!)
但是:更具体地针对您的特定用例:获取timezone database信息的方法比抓取特定网页更好(除此之外:请注意网页实际上提到您不允许复制其内容)。甚至现有的库已经使用了这些信息,例如参见python-dateutil。
答案 1 :(得分:4)
避免使用正则表达式来解析HTML,它们根本不适合它,你想要一个像BeautifulSoup这样的DOM解析器......
其他一些选择
所有这些都能够合理地容忍格式不正确的HTML。
答案 2 :(得分:0)
我建议使用与PHP捆绑在一起的XML解析器(如DOMDocument :: loadHTMLFile)加载文档,然后使用XPath来获取所需的数据。
这不是最快的方式,但最具可读性(在我看来)。您可以使用Regex,它可能会更快一些,但风格很差(难以调试,难以阅读)。
编辑:实际上这很难,因为您提到的页面不是有效的HTML(请参阅validator.w3.org)。特别是没有开/关标签的标签很重要。
看起来像xmlstarlet(http://xmlstar.sourceforge.net/(很棒的工具))能够修复问题(运行xmlstarlet fo -R)。 xmlstarlet还可以执行xpath和xslt脚本,它可以帮助您使用简单的shell脚本提取数据。
答案 3 :(得分:0)
在构建SerpAPI时,我们测试了许多平台/解析器。
这是Python的基准测试结果。
有关更多信息,这里是有关Medium的全文: https://medium.com/@vikoky/fastest-html-parser-available-now-f677a68b81dd
答案 4 :(得分:-2)
正则表达式的效率优于DOM解析器。
看看这个比较:
您可以在网上搜索更多内容。