代码之家  ›  专栏  ›  技术社区  ›  jsay

python3 xpath无法访问子节点(AttributeError:“NoneType”对象没有属性“text”)

  •  0
  • jsay  · 技术社区  · 9 年前

    需要帮助解决一些我没能找到的问题

    我有一个这样的xml:

    <forecast xmlns="http://weather.yandex.ru/forecast" country_id="8996ba26eb0edf7ea5a055dc16c2ccbd" part="Лен Стокгольм" link="http://pogoda.yandex.ru/stockholm/" part_id="53f767b78d8f180c28d55ebda1d07e0c" lat="59.381981" slug="stockholm" city="Стокгольм" climate="1" country="Швеция" region="10519" lon="17.956846" zoom="12" id="2464" source="Station" exactname="Стокгольм" geoid="10519">
    <fact>...</fact>
    <yesterday id="435077826">...</yesterday>
    <informer>...</informer>
    <day date="2016-04-18">
        <sunrise>05:22</sunrise>
        <sunset>20:12</sunset>
        <moon_phase code="growing-moon">14</moon_phase>
        <moonrise>15:53</moonrise>
        <moonset>04:37</moonset>
        <biomet index="3" geomag="2" low_press="1" uv="1">...</biomet>
        <day_part typeid="1" type="morning">...</day_part>
        <day_part typeid="2" type="day">...</day_part>
        <day_part typeid="3" type="evening">...</day_part>
        <day_part typeid="4" type="night">...</day_part>
        <day_part typeid="5" type="day_short">
            <temperature>11</temperature>
        </day_part>
    </day>
    </forecast>
    

    (整个xml可以在 https://export.yandex.ru/weather-ng/forecasts/2464.xml ). 需要测量温度。text(11),尝试此代码:

    import urllib.request
    import codecs
    import lxml
    from xml.etree import ElementTree as ET
    
    def gen_ns(tag):
        if tag.startswith('{'):
            ns, tag = tag.split('}') 
            return ns[1:]
        else:
            return ''
    with codecs.open(fname, 'r', encoding = 'utf-8') as t:
            town_tree = ET.parse(t)
            town_root = town_tree.getroot() 
            print (town_root)
    
            namespaces = {'ns': gen_ns(town_root.tag)}
            print (namespaces)
    
            for day in town_root.iterfind('ns:day', namespaces):
                date = (day.get('date'))
                print (date)
                day_temp = day.find('.//*[@type="day_short"]/temperature')  
                print (day_temp.text)
    

    得到:

    Traceback (most recent call last):
    File "weather.py", line 154, in <module>
        print (day_temp.text)
    AttributeError: 'NoneType' object has no attribute 'text'
    

    我的xpath怎么了?我可以得到 ('.//*[@type="day_short"]') ,但无法获取其子级(温度)文本 谢谢大家!

    1 回复  |  直到 9 年前
        1
  •  1
  •   Keith Hall    9 年前

    xml文档包含默认名称空间,XPath没有默认名称空间的概念。在XPath中,您要么需要将其映射到前缀(就像使用 day )或使用其他方法,如 local-name 以确定元素的标记名是否与所需匹配。

    .//*[@type="day_short"]/*[local-name()='temperature']
    

    day_temp = day.find('.//*[@type="day_short"]/ns:temperature', namespaces)