1

私はこのXMLファイルを持っています:

<movie id = 0> 
  <Movie_name>The Shawshank Redemption   </Movie_name> 
  <Address>http://www.imdb.com/title/tt0111161/
  </Address> 
  <year>1994  </year> 
  <stars>Tim Robbins  Morgan Freeman  Bob Gunton    </stars> 
  <plot> plot...
  </plot> 
  <keywords>Reviews, Showtimes</keywords>
</movie>

<movie id = 1> 
  <Movie_name>Inglourious Basterds   </Movie_name> 
  <Address>http://www.imdb.com/title/tt0361748/
  </Address> 
  <year>2009  </year> 
  <stars>Brad Pitt  M&#xE9;lanie Laurent  Christoph Waltz    </stars> 
  <plot>plot/... 
  </plot> 
  <keywords>Reviews, credits  </keywords>
</movie>

各映画の特定のデータを抽出するファイルをどのように繰り返すことができますか?私は映画0を意味します:その名前、住所、年など。

入力ファイルの構造は必須であるため、ループ中にデータ抽出を実行できます。

どうもありがとう。

4

3 に答える 3

3

編集-改善されたXML入力を取り入れます

@Lattywareのコメントのように、入力を検証することを強くお勧めします。無効なXMLとHTMLを使用すると、BeautifulSoupは使用可能なものを回復するのに適していることがわかりました。簡単に試してみると、次のようになります。

from BeautifulSoup import BeautifulSoup

# Note: I have added the <movielist> root element
xml = """<movielist>
<movie id = 0> 
  <Movie_name>The Shawshank Redemption   </Movie_name> 
  <Address>http://www.imdb.com/title/tt0111161/
  </Address> 
  <year>1994  </year> 
  <stars>Tim Robbins  Morgan Freeman  Bob Gunton    </stars> 
  <plot> plot...
  </plot> 
  <keywords>Reviews, Showtimes</keywords>
</movieNum>

<movie id = 1> 
  <Movie_name>Inglourious Basterds   </Movie_name> 
  <Address>http://www.imdb.com/title/tt0361748/
  </Address> 
  <year>2009  </year> 
  <stars>Brad Pitt  M&#xE9;lanie Laurent  Christoph Waltz    </stars> 
  <plot>plot/... 
  </plot> 
  <keywords>Reviews, credits  </keywords>
</movieNum>

</movielist>"""

soup = BeautifulSoup(xml)
movies = soup.findAll('movie')

for movie in movies:
    id_tag = movie['id']
    name = movie.find("movie_name").text
    url = movie.find("address").text
    year = movie.find("year").text
    stars = movie.find("stars").text
    plot = movie.find("plot").text
    keywords = movie.find("keywords").text
    for item in (id_tag, name, url, year, stars, plot, keywords):
        print item
    print '=' * 50

これにより、次のように出力されます(IDタグにアクセスできるようになりました)。

0
The Shawshank Redemption
http://www.imdb.com/title/tt0111161/
1994
Tim Robbins  Morgan Freeman  Bob Gunton
plot...
Reviews, Showtimes
==================================================
1
Inglourious Basterds
http://www.imdb.com/title/tt0361748/
2009
Brad Pitt  M&#xE9;lanie Laurent  Christoph Waltz
plot/...
Reviews, credits
==================================================

それはうまくいけばあなたにスタートを与えるでしょう...それはここからのみ良くなることができます。

于 2012-04-28T11:55:41.350 に答える
3

あなたはチェックアウトしたくなるでしょうxml.etree.ElementTree

また、有効なXMLがないため、問題が発生する可能性があることにも注意してください。有効なXMLは、おそらく次のようになります。

<movie id="0"> 
  <name>The Shawshank Redemption</name> 
  <url>http://www.imdb.com/title/tt0111161/</url> 
  <year>1994</year> 
  <stars>
    <star>Tim Robbins</star>
    <star>Morgan Freeman</star>
    <star>Bob Gunton</star>
  </stars> 
  <plot>plot...</plot> 
  <keywords>
    <keyword>Reviews</keyword>
    <keyword>Showtimes</keyword>
  </keywords>
</movie>

小文字のタグ名と属性に注意してください(<movieNum = 0>意味がありません)。また、上部にXML宣言(のような<?xml version="1.0" encoding="UTF-8" ?>)が必要になります。XMLは、 XML検証で、またはxmllintを使用して検証できます。

有効なXMLを取得したら、それを解析して、を使用して反復するiterparse()か、解析してから構築された要素ツリーを反復処理できます。

于 2012-04-28T11:32:03.743 に答える
2

BeutifulSoupはより寛容であり、HTMLにも使用できます(一部の囲みタグはオプションです)。ElementTreeは、XMLが有効な場合にのみ使用できます。フラグメントを単一の要素にラップすることで、部分的に有効にすることができます。属性値は引用符で囲む必要があります。クラスが作成された次のアプローチを試して、 1つのムービー要素Movieから情報をキャプチャします。このクラスはdictから派生しており、dictと同じくらい柔軟です。ただし、収集した情報から処理された値を返す独自のメソッドを作成できます。

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as ET

class Movie(dict):

    def __init__(self, movie_element):
        assert movie_element.tag == 'movie'  # we are able to process only that
        self['id'] = movie_element.attrib['id']  
        for e in movie_element:
            self[e.tag] = e.text.strip()

    def name(self):
        return self['Movie_name']

    def url(self):
        return self['Address']

    def year(self):
        return self['year']     

    def stars(self):
        return self['stars']

    def plot(self):
        return self['plot']

    def keywords(self):
        return self['keywords']

    def __str__(self):
        lst = []
        lst.append(self.name() + ' (' + self.year() + ')')
        lst.append(self.stars())
        lst.append(self.url())
        return '\n'.join(lst)


fragment = '''\
<movie id = "0"> 
  <Movie_name>The Shawshank Redemption   </Movie_name> 
  <Address>http://www.imdb.com/title/tt0111161/
  </Address> 
  <year>1994  </year> 
  <stars>Tim Robbins  Morgan Freeman  Bob Gunton    </stars> 
  <plot> plot...
  </plot> 
  <keywords>Reviews, Showtimes</keywords>
</movie>

<movie id = "1"> 
  <Movie_name>Inglourious Basterds   </Movie_name> 
  <Address>http://www.imdb.com/title/tt0361748/
  </Address> 
  <year>2009  </year> 
  <stars>Brad Pitt  Melanie Laurent  Christoph Waltz    </stars> 
  <plot>plot/... 
  </plot> 
  <keywords>Reviews, credits  </keywords>
</movie>
'''

fixed_fragment = '<root>\n' + fragment + '</root>'
##print fixed_fragment

tree = ET.fromstring(fixed_fragment)
movies = []
for m in tree:
    movies.append(Movie(m))

for movie in movies:
    print '\n------------------'
    print movie    

それは私のコンソールに印刷されます:

------------------
The Shawshank Redemption (1994)
Tim Robbins  Morgan Freeman  Bob Gunton
http://www.imdb.com/title/tt0111161/

------------------
Inglourious Basterds (2009)
Brad Pitt  Melanie Laurent  Christoph Waltz
http://www.imdb.com/title/tt0361748/

非ASCII文字を置き換えたことに注意してください。エンコーディングの問題は個別に解決する必要があります。

于 2012-04-28T12:32:58.237 に答える