在python中用XML解析html页面

2024-10-01 15:32:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图将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>

我想获得关于drstx和{}字段的信息,但我不知道如何使用XML函数。我试图读取HTML文件,然后创建和箭头来存储前面提到的路径后的内容,但我不能让它工作。在

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


Tags: httpsourcehtmldtxmlloctnfc
2条回答

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

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)

印刷品:

^{pr2}$

这使得将这个片段解析器与pyparsing的其他特性(如运行时解析操作、语义检查等)结合起来很容易

编辑

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

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)

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

请考虑由Python提供的几种结构化类型,而不是其中一种。您有几种选择:

A.使用dicts。在

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

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

B.使用namedtuples。在

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”,那么就不能使用namedtuple。另外,namedtuples是不可变的-您不能接受现有的FCDatafc并用fc.dt = "new datetime value"将其赋值到其dt字段中。另一方面,口述允许这样做。在

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"就可以了。在

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

fcArray = fcTag.searchString(htmltext)

pyparsing返回ParseResults,它结合了dict和namedtuples的行为。就像在使用fc = fcArray[i]访问第i个条目之前一样。您可以使用fc.dtfc['dt']来读取dt属性。您可以读取fc.dt,但不能像namedtuple那样分配给它。您可以将赋值给fc['dt'],就像dict一样

如果您可以轻松地提取天气标签,那么可以使用Python附带的^{} API。在

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文档,elementtreeapi可以很好地处理它。在

否则,您需要切换到HTML解析器。您可以安装^{} library;该库支持相同的elementtreeapi,但包含一个专用的HTML解析器。在

您也可以使用BeautifulSoup作为替代的htmlapi。事实上,lxml和{}可以协同工作,为您的任务提供一个api选择;使用任何一个对您来说更容易的api。在

lxml和{}都是外部库。在

相关问题 更多 >

    热门问题