2017-01-11 5 views
1

Pythtonと美しいスープを学んでいます。人気のある赤ちゃんの名前を含むhtmlファイルを使用してGoogle演習を行っています。別の年のために(例えば、baby1990.htmlなど)。 https://developers.google.com/edu/python/exercises/baby-names'ResultSet'オブジェクトには、関数内のBeautiful Soupに 'findAll'というエラーメッセージがありません。

各HTMLファイルは次のようになります赤ちゃんの名前データを持つテーブル含まれています:

enter image description here

を私は赤ちゃんの名前を抽出機能を構成しているあなたは、あなたがここに興味を持っている場合は、このデータセットを見つけることができますHTMLファイルからそれらをデータフレーム、辞書内のデータフレーム、および単一のデータフレームに集約されたすべてのデータフレームに格納します。

各htmlファイルには2つのテーブルがあります。独特の属性がまとめ=「フォーマット」である。このラインで

<table width="100%" border="0" cellspacing="0" cellpadding="4" summary="formatting"> 

:赤ちゃんデータを含むテーブルは、次のHTMLコードを持っています。

私が受け取ったフィードバックに基づいて編集された書いた機能は以下の通りです:

def babynames(path): 

# This function takes the path of the directory where the html files are stored and returns a list containing the 
# a dataframe which encompasses all the tabular baby-names data in the files and as well as a dictionary holding 
# a separate dataframe for each html file 

# 0: Initialize objects 
dicnames = {} # will hold the dataframes containing the tabular data of each year 
dfnames = pd.DataFrame([]) # will hold the aggregate data 

# 1: Create a list containing the full paths of the baby files in the directory indicated by the path argument of the babynames 
# function 
allfiles = files(path) 

# 2: Begin the looping through the files 

for file in allfiles: 
     with open(file,"r") as f: soup = bs(f.read(), 'lxml') # Convert the file to a soup 

     # 3. Initialize empty lists to hold the contents of the cells 
     Rank=[] 
     Baby_1 =[] 
     Baby_2 =[] 
     df = pd.DataFrame([]) 

     # 4. Extract the Table containing the Baby data and loop through the rows of this table 

     for row in soup.select("table[summary=formatting] tr"): 

     # 5. Extract the cells 

      cells = row.findAll("td") 

      # 6. Convert to text and append to lists 
      try: 
       Rank.append(cells[0].find(text=True)) 
       Baby_1.append(cells[1].find(text=True)) 
       Baby_2.append(cells[2].find(text=True)) 
      except: 
       print "file: " , file 
       try: 
         print "cells[0]: " , cells[0] 
       except: 
         print "cells[0] : NaN" 
       try: 
         print "cells[1]: " , cells[1] 
       except: 
         print "cells[1] : NaN"  
       try: 
         print "cells[2]: " , cells[2] 
       except: 
         print "cells[2] : NaN" 

      # 7. Append the lists to the empty dataframe df 
      df["Rank"] = Rank 
      df["Baby_1"] = Baby_1 
      df["Baby_2"] = Baby_2 

      # 8. Append the year to the dataframe as a separate column 
      df["Year"] = extractyear(file) # Call the function extractyear() defined in the environment with input 
              # the full pathname stored in variable file and examined in the current 
              # iteration 

      # 9. Rearrange the order of columns 
      # df.columns.tolist() = ['Year', 'Rank', 'Baby_1', 'Baby_2'] 

      #10. Store the dataframe to a dictionary as the value which key is the name of the file 
      pattern = re.compile(r'.*(baby\d\d\d\d).*') 
      filename = re.search(pattern, file).group(1) 
      dicnames[filename] = df 

    # 11. Combine the dataframes stored in the dictionary dicname to an aggregate dataframe dfnames 
     for key, value in dicnames.iteritems(): 
      dfnames = pd.concat[dfnames, value] 

    # 12. Store the dfnames and dicname in a list called result. Return result. 
     result = [dfnames, dicnames] 
     return result 

私は(私はhtmlファイルを格納している私のディレクトリのパス)指定されたパスを持つ関数を実行します

--------------------------------------------------------------------------- 


file: C:/Users/ALEX/MyFiles/JUPYTER NOTEBOOKS/google-python-exercises/babynames/baby1990.html 
cells[0]: cells[0] : NaN 
cells[1]: cells[1] : NaN 
cells[2]: cells[2] : NaN 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-72-5c9ebdc4dcdb> in <module>() 
----> 1 result = babynames(path) 

<ipython-input-71-a0263a6790da> in babynames(path) 
    54 
    55     # 7. Append the lists to the empty dataframe df 
---> 56     df["Rank"] = Rank 
    57     df["Baby_1"] = Baby_1 
    58     df["Baby_2"] = Baby_2 

C:\users\alex\Anaconda2\lib\site-packages\pandas\core\frame.pyc in __setitem__(self, key, value) 
    2355   else: 
    2356    # set column 
-> 2357    self._set_item(key, value) 
    2358 
    2359  def _setitem_slice(self, key, value): 

C:\users\alex\Anaconda2\lib\site-packages\pandas\core\frame.pyc in _set_item(self, key, value) 
    2421 
    2422   self._ensure_valid_index(value) 
-> 2423   value = self._sanitize_column(key, value) 
    2424   NDFrame._set_item(self, key, value) 
    2425 

C:\users\alex\Anaconda2\lib\site-packages\pandas\core\frame.pyc in _sanitize_column(self, key, value) 
    2576 
    2577    # turn me into an ndarray 
-> 2578    value = _sanitize_index(value, self.index, copy=False) 
    2579    if not isinstance(value, (np.ndarray, Index)): 
    2580     if isinstance(value, list) and len(value) > 0: 

C:\users\alex\Anaconda2\lib\site-packages\pandas\core\series.pyc in _sanitize_index(data, index, copy) 
    2768 
    2769  if len(data) != len(index): 
-> 2770   raise ValueError('Length of values does not match length of ' 'index') 
    2771 
    2772  if isinstance(data, PeriodIndex): 

ValueError: Length of values does not match length of index 

:アウト

result = babynames(path) 

:私は、次のエラーメッセージが表示されますセル[0]、セル1、セル[2]は値を持つ必要があります。

私は、次のHTMLコードによって識別される1つの以上のテーブル直前あり述べたように:

<table width="100%" border="0" cellspacing="0" cellpadding="4"> 

は、私はテーブルを指定していない機能のバージョンを実行している - 私はそれが認められていませんでしたhtmlファイルに2つのテーブルがありました。そのバージョンで私はこのタイプのエラーを取得しませんでした。私は6行目のエラーメッセージにtryステートメントの識別が適切でないことがわかりました。私は理解できませんでした。また、9行目のエラーメッセージはデータフレームの列を再配置しようとしました。

あなたのアドバイスは高く評価されます。

+0

'right_table.find_all(" tr ")'を試してください。 'findAll()'を 'find_all()'に置き換えてください。 – MYGz

答えて

2

right_tableResultSetインスタンスである(基本的に、要素を表すTagインスタンスのリスト)は、それがfindAll()又はfind_all()方法を有していません。それらの

代わりに、あなたはright_tableの要素のいずれかのループはあなたが持っている場合は、複数:単一のものがある場合には

right_table = soup.find_all("table", summary_ = "formatting") 

for table in right_table: 
    for row in table.findAll("tr"): 
     # ... 

あるいは、使用find()

right_table = soup.find("table", summary_ = "formatting") 

あるいは、単一のCSSセレクタを使用してください。

for row in soup.select("table[summary=formatting] tr"): 
    # ... 
関連する問題