2017-09-20 6 views
0

私はESPNから、いくつかのスケジュール表をこすりしようとしています:http://www.espn.com/nba/schedule/_/date/20171001ウェブスクレイピング - bd4を使用して<td foo = blahblah> TEXT</td>から「blahblah」を取得しますか?

import requests 
import bs4 

response = requests.get('http://www.espn.com/nba/schedule/_/date/20171001') 
soup = bs4.BeautifulSoup(response.text, 'lxml') 
print soup.prettify() 

table = soup.find_all('table') 

data = [] 
for i in table: 
    rows = i.find_all('tr') 
    for row in rows: 
     cols = row.find_all('td') 
     cols = [col.text.strip() for col in cols] 
     data.append([col for col in cols if col]) 

私のコードは、日付情報不足している出力を除いて正常に動作します:いくつかの調査の後

[ 
    "Phoenix PHX", 
    "Utah UTAH", 
    "394 tickets available from $6" 
], 
[], 
[ 
    "Miami MIA", 
    "Orlando ORL", 
    "1,582 tickets available from $12" 
] 

を、私は気づい日付と時刻の情報は次のようにタグ内にラップされます。

<td data-behavior="date_time" data-date="2017-10-07T23:00Z"><a data-dateformat="time1" href="/nba/game?gameId=400978807" name="&amp;lpos=nba:schedule:time"></a></td> 

これは、彼らはなぜこのようにしているのかを決して実際に理解したことはありません。私の出力に "2017-10-07T23:00Z"を取得するために、オープンタグ内のテキストを抽出するにはどうすればいいですか?

答えて

1

attrsプロパティには、値を取得するために使用できる属性の辞書が含まれています。空の行がいくつか存在するため、長さのチェックを追加しました。

for i in table: 
    rows = i.find_all('tr') 
    for row in rows: 
     cols = row.find_all('td') 
     date_data = None 
     if len(cols) > 2: 
      date_data = cols[2].attrs['data-date'] 
     cols = [col.text.strip() for col in cols] 
     dat = [col for col in cols if col] 
     if date_data: 
      dat.append(date_data) 
     data.append(dat) 

PS:上記のスニペットは

1

:-)最適化することができ、そのテーブルの一部tdタグはattributesが含まれている

あなたは以下のようにループのために修正することを試みることができます。あなたはdictを返すattrs()を呼び出すことによってtdの属性にアクセスすることができます

>>> td = soup.select('tr')[1].select('td')[2] 
>>> td 
<td data-behavior="date_time" data-date="2017-10-01T22:00Z"><a data-dateformat="time1" href="/nba/game?gameId=400978817" name="&amp;lpos=nba:schedule:time"></a></td> 
>>> td.attrs 
{'data-date': '2017-10-01T22:00Z', 'data-behavior': 'date_time'} 
>>> td.attrs['data-date'] 
'2017-10-01T22:00Z' 

そのためには、その属性が存在する場合は、日付を返す関数を作成するか、単にtdのテキストを返すことができます。

import requests 
import bs4 

def date_or_text(td): 
    if 'data-date' in td.attrs: 
     return td.attrs['data-date'] 
    return td.text 

def extract_game_information(tr): 
    tds_with_blanks = (date_or_text(td) for td in tr.select('td')) 
    return [data for data in tds_with_blanks if data] 

response = requests.get('http://www.espn.com/nba/schedule/_/date/20171001') 
soup = bs4.BeautifulSoup(response.text, 'lxml') 

data = [extract_game_information(tr) for tr in soup.select('tr')] 
関連する問題