2016-11-02 10 views
1

私はテキストファイルへのリンクのリストを保存するクラスプロジェクトを行っています。PythonとElementTreeを使ってXMLを解析する

私はXMLを与えて、のすべてのURLを反復しようとしていますが、すべてのURLのに問題があります。

私は要素ツリーを使用しようとしましたが、私は多くの他の質問を読んでそれを反復することはできませんでした。私はあなたが効率的にXMLファイルを解析するlxmlを使用することをお勧めこの

<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3"> 
    <url> 
    <loc> 
     http://www.crawlingcourse.com/item-3911512 
    </loc> 
    </url> 
<url>.... 
+1

これまでのコードはどのようになっていますか?どのように動作していないのですか? – larsks

+0

この例では、XMLが正しい(すべての要素が閉じられている、doctypeなど)ことを確認したいだけですか? – Eugene

答えて

4

よう

構造を助けてください。

from lxml import etree 

あなたのXMLサンプルは、よく形成されていない、私はこのようにそれを固定:あなたがetree.parse()を使用することができ、ファイルを解析するには

content = """\ 
<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3"> 
    <url> 
    <loc> 
     http://www.crawlingcourse.com/item-3911512 
    </loc> 
    </url> 
</urlset>""" 

。このサンプルは、文字列であるので、しかし、私はetree.XML()を使用します。

tree = etree.XML(content) 

XMLツリー内の要素を検索する自然な方法は、XPathを使用しています。

loc_list = tree.xpath("//url/loc") 

をしかし、あなたは何を得るんでしょう:たとえば、あなたがそれを行うことができます「http://www.crawlingcourse.com/sitemap/1.3」:

for loc in loc_list: 
    print(loc.text) 
# None 

理由は、それはあなたの問題はおそらく、<urlset>は、デフォルトの名前空間を使用することです。

これを機能させるには、この名前空間にxpath()関数を使用する必要があります。このようなあなたのXPath式でs接頭辞を使用し、その後

NS = {'s': "http://www.crawlingcourse.com/sitemap/1.3"} 

:「S」:のは、この名前空間に名前を挙げてみましょう、あなたのXMLがインデントされるので

loc_list = tree.xpath("//s:url/s:loc", namespaces=NS) 

for loc in loc_list: 
    print(loc.text) 
#  http://www.crawlingcourse.com/item-3911512 

、あなたがストリップする必要がありますスペース:

for loc in loc_list: 
    url = loc.text.strip() 
    print(url) 
# http://www.crawlingcourse.com/item-3911512 
+0

説明する時間をとってくれてありがとう@Laurent。あなたは私の問題を解決し、それが実際にどのように働くか教えてくれました。ありがとう – hahu

1

まあ、問題は本当に名前空間です。

ここで働いているコードは:あなたが<urlset xmlns="http://www.crawlingcourse.com/sitemap/1.3">を追加したい場合は

from xml.etree.cElementTree import XML, fromstring, tostring, ElementTree 
xml_string = '<?xml version="1.0"?><urlset><url><loc>http://www.crawlingcourse.com/item-3911512</loc></url></urlset>' 
tree = ElementTree(fromstring(xml_string)) 
print [elem.text for elem in tree.iter(tag='loc')] 

、タグが異なることを行っています。からhttp://www.w3schools.com/xml/xml_namespaces.asp

XML名前空間 - xmlns属性。 XMLに接頭辞を使用する場合は、接頭辞のための 名前空間を定義する必要があります。名前空間は、要素の開始タグのxmlns属性によって と定義できます。ネームスペース 宣言の構文は次のとおりです。 xmlns:prefix = "URI"

あまりにも私を捨てました!

関連する問題