2017-08-19 6 views
0

複数のページをループして、PythonとBeautifulsoupでデータをスクラップしようとしています。私のスクリプトは1ページで動作しますが、複数のページを反復しようとすると、最後のページからのデータが返されます。私は、ループするか、またはplayer_dataのリストを格納/追加する方法に何か問題があると思う。Pythonで複数のページを綺麗にするBeautifulsoup - 最後のページからのみデータを返す

これまで私がこれまで持っていたことは、どんな助けでも大歓迎です。

#! python3 
# downloadRecruits.py - Downloads espn college basketball recruiting database info 

import requests, os, bs4, csv 
import pandas as pd 

# Starting url (class of 2007) 
base_url = 'http://www.espn.com/college-sports/basketball/recruiting/databaseresults/_/class/2007/page/' 

# Number of pages to scrape (Not inclusive, so number + 1) 
pages = map(str, range(1,3)) 

# url for starting page 
url = base_url + pages[0] 

for n in pages: 
    # Create url 
    url = base_url + n 

    # Parse data using BS 
    print('Downloading page %s...' % url) 
    res = requests.get(url) 
    res.raise_for_status() 

    # Creating bs object 
    soup = bs4.BeautifulSoup(res.text, "html.parser") 

    table = soup.find('table') 

    # Get the data 
    data_rows = soup.findAll('tr')[1:] 

    player_data = [] 
    for tr in data_rows: 
     tdata = [] 
     for td in tr: 
      tdata.append(td.getText()) 

      if td.div and td.div['class'][0] == 'school-logo': 
       tdata.append(td.div.a['href']) 

     player_data.append(tdata) 

print(player_data) 
+3

「print(player_data)」の前に4つのスペースを追加します。 – PRMoureu

答えて

1

あなたはそうでないだけ最後の繰り返しの結果が保存されます、あなたのループの外であなたのplayer_dataリスト定義を持つ必要があります。

+0

ありがとう@Kostas Drk。質問 - これはCSVに保存する場合にも適用されますか? f_outputとしてopen( 'bballRecruits.csv'、 'w')を使用して最後のページのみを保存します: csv_output = csv.writer(f_output) csv_output.writerows(player_data) – NateRattner

+0

@NateRattnerはい、あなたがそのリストを使って何をしていても、それはその中に格納されているものの問題です。 –

1

これは、期待どおりの結果に応じてインデントの問題または宣言の問題です。

  • あなたがページごとに結果を印刷する必要がある場合:

あなたは、印刷(player_data)の前に4つのスペースを追加することによってこの問題を解決することができます。

forループブロックの外側にprintステートメントを置くと、ループが終了した後でprintステートメントが1回だけ実行されます。したがって、表示できる唯一の値は、forループの最後の反復から漏れたplayer_dataの最後の値です。

  • あなたがplayer_dataですべての結果を保存し、最後にそれを印刷したい場合:

あなたがplayer_data外を宣言して、ループの前にしなければなりません。

player_data = [] 
for n in pages: 
    # [...] 
+0

OPは、印刷されるものだけでなく、返されたデータについても尋ねています。 –

+0

@KostasDrk、それを指摘してくれてありがとう、何が期待されているかわからない... – PRMoureu

+0

ありがとう@PRMoureu。私はもっ​​と明確にすべきだった - 私はすべての結果をplayer_dataに保存し、最後にそれを印刷したいと思った。これは完璧でした。 – NateRattner

0
import requests 
from bs4 import BeautifulSoup 

# Starting url (class of 2007) 
base_url = 'http://www.espn.com/college-sports/basketball/recruiting/databaseresults/_/class/2007/page/' 

# Number of pages to scrape (Not inclusive, so number + 1) 
pages = list(map(str,range(1,3))) 
# In Python 3, map returns an iterable object of type map, and not a subscriptible list, which would allow you to write map[i]. To force a list result, write 
# url for starting page 
url = base_url + pages[0] 

for n in pages: 
    # Create url 
    url = base_url + n 

    # Parse data using BS 
    print('Downloading page %s...' % url) 
    res = requests.get(url) 
    res.raise_for_status() 

    # Creating bs object 
    soup = BeautifulSoup(res.text, "html.parser") 

    table = soup.find('table') 

    # Get the data 
    data_rows = soup.findAll('tr')[1:] 

    player_data = [] 
    for tr in data_rows: 
     tdata = [] 
     for td in tr: 
      tdata.append(td.getText()) 

      if td.div and td.div['class'][0] == 'school-logo': 
       tdata.append(td.div.a['href']) 

     player_data.append(tdata) 

print(player_data) 
関連する問題