2

我试图让 python 从 HTML 页面解析这个 XML 代码:

<weather>
    <loc mobiurl="http://foreca.mobi/?lon=-8.6110&lat=41.1496&source=navi/" url="http://foreca.com/?lon=-8.6110&lat=41.1496&source=navi/">
        <obs station="Porto / Pedras Rubras" dist="11 km NW" dt="2013-03-06 17:00:00" t="14" tf="14" s="d320" wn="S" ws="8" p="997" rh="94" v="5000"/>
        <fc dt="2013-03-07" tx="16" tn="11" s="d220"/>
        <fc dt="2013-03-08" tx="15" tn="10" s="d220"/>
        <fc dt="2013-03-09" tx="15" tn="10" s="d220"/>
    </loc>
</weather>

我想获取有关dr、和字段的信息s,但我不知道如何使用 XML 函数来完成。我尝试读取 HTML 文件,然后在前面所说的路径之后创建和箭头来存储内容,但我无法让它工作。txtn

有什么简单的方法可以用 python 获取数据吗?

4

2 回答 2

0

如果您可以轻松提取天气标签,则可以使用Python 附带的xml.etree.ElementTreeAPI 。

import xml.etree.ElementTree as ET
tree = ET.fromstring(weatherdata)

for fcelem in tree.findall('.//fc'):
    print fcelem.attrib['tx'], fcelem.attrib['tn']

如果要从 HTML 文档中提取它,则取决于 HTML 的格式是否正确。如果它是 XHTML 文档,ElementTree API 可以很好地处理它。

否则,您需要改用 HTML 解析器。您可以安装lxml;该库支持相同的 ElementTree API,但包含专用的 HTML 解析器。

您还可以将BeautifulSoup用于替代 HTML API。事实上,lxml并且BeautifulSoup可以协同工作,为您的任务提供 API 选择;使用对您来说更容易的那个。

两者 都是外部库lxmlBeautifulSoup

于 2013-03-06T18:19:26.283 回答
0

makeHTMLTags使用该库的方法(makeHTMLTags返回一对表达式,用于开始和结束标签,但在您的示例中,只需要开始标签)可以通过 pyparsing 轻松完成一些 HTML 抓取:

from pyparsing import makeHTMLTags

fcTag = makeHTMLTags("fc")[0]
tagAttrs = 'dt s tx tn'.split()

for match in fcTag.searchString(htmltext):
    print ' '.join("%s:%s" % (attr,match[attr]) for attr in tagAttrs)

印刷:

dt:2013-03-07 s:d220 tx:16 tn:11
dt:2013-03-08 s:d220 tx:15 tn:10
dt:2013-03-09 s:d220 tx:15 tn:10

这使得很容易将此片段解析器与 pyparsing 的其他功能结合起来,例如运行时解析操作、语义检查等。

编辑

如果您希望所有 dt、s 等在它们各自的列表中(在 Python 中,我们称它们为“列表”,而不是“向量”),请执行以下操作:

dtArray = []
sArray = []
txArray = []
tnArray = []
for match in fcTag.searchString(htmltext):
    dtArray.append(match.dt)
    sArray.append(match.s)
    txArray.append(match.tx)
    tnArray.append(match.tn)
    print ' '.join("%s:%s" % (attr,match[attr]) for attr in tagAttrs)

我以前见过这样的代码,这是一种糟糕的数据结构模式。您可以通过获取 , 等来访问原始表的第 i 个条目的dtArray[i]sArray[i]

请考虑使用 Python 提供的几种结构化类型之一。您有几个可供选择:

A. 使用字典。

fcArray = []
for match in fcTag.searchString(htmltext):
    fcArray.append(dict((attr,match[attr]) for attr in tagAttrs))

现在要获得第 i 个条目,只需 get并从该 dictfc = fcArray[i]访问等值。fc['dt']fc['s']

B. 使用命名元组。

from collections import namedtuple
FCData = namedtuple("FCData", tagAttrs)

fcArray = []
for match in fcTag.searchString(htmltext):
    fcArray.append(FCData(*(match[attr] for attr in tagAttrs)))

您再次使用fc = fcArray[i]来获取第 i 个条目,但现在您使用 , 等访问值fc.dtfc.s我发现这种形式比 dict 形式看起来更干净,但有一些限制。所有的标签名称都必须是合法的 Python 标识符,所以如果你有一个标签“rise/run”,那么你就不能使用命名元组。此外,namedtuples 是不可变的 - 您不能获取现有的 FCDatafcdt使用fc.dt = "new datetime value". 另一方面,dicts 将允许这样做。

C. 使用对象。最简单的是创建空对象实例的“bag”类型对象,您可以通过简单的赋值或 setattr 调用为其添加属性:

class FCData(object): pass

fcArray = []
for match in fcTag.searchString(htmltext):
    fc = FCdata()
    for attr in tagAttrs:
        setattr(fc, attr, match[attr])
    fcArray.append(fc)

您使用 获得第 i 个条目fc = fcArray[i],并且像 namedtuple 一样,您使用等获得属性fc.dt。但是如果需要,您也可以修改属性,并且分配fc.dt = "new datetime value"将起作用。

D. 只需使用 pyparsing 的 searchString 方法创建的对象。

fcArray = fcTag.searchString(htmltext)

pyparsing 返回ParseResults,它结合了 dicts 和 namedtuples 的行为。就像在您使用 访问第 i 个条目之前一样fc = fcArray[i]。您可以使用或读取dt属性。你可以阅读,但你不能分配给它,就像命名元组一样。您可以分配给,就像字典一样。fc.dtfc['dt']fc.dtfc['dt']

于 2013-03-06T18:52:32.710 回答