2017-11-20 1 views
1

Im Codebeispiel unten, 3 der 5 Elemente, die ich versuche, Rückgabewerte wie erwartet zu scracken. 2 (goals_scored und assists) gibt keine Werte zurück. Ich habe überprüft, dass die Daten auf der Webseite vorhanden sind und dass ich das korrekte Attribut verwende, aber nicht sicher, warum die Ergebnisse nicht zurückgegeben werden. Gibt es etwas Offensichtliches, das ich übersehe?Extrahieren von Webdaten mit Beautiful Soup (Python 2.7)

import sys 
from bs4 import BeautifulSoup as bs 
import urllib2 
import datetime as dt 
import time 
import pandas as pd 

proxy_support = urllib2.ProxyHandler({}) 
opener = urllib2.build_opener(proxy_support) 

player_name=[] 
club =[] 
position = [] 
goals_scored = [] 
assists = [] 

for p in range(25): 
player_url = 'http://www.mlssoccer.com/stats/season?page={p}&franchise=select&year=2017&season_type=REG&group=goals'.format( 
     p=p) 
page = opener.open(player_url).read() 
player_soup = bs(page,"lxml") 
print >>sys.stderr, '[{time}] Running page {n}...'.format( 
     time=dt.datetime.now(), n=p) 
length = len(player_soup.find('tbody').findAll('tr')) 

for row in range(0, length): 
    try: 
     name = player_soup.find('tbody').findAll('td', attrs={'data-title': 'Player'})[row].find('a').contents[0] 
     player_name.append(name) 
     team = player_soup.find('tbody').findAll('td', attrs={'data-title': 'Club'})[row].contents[0] 
     club.append(team) 
     pos = player_soup.find('tbody').findAll('td', attrs={'data-title': 'POS'})[row].contents[0] 
     position.append(pos) 
     goals = player_soup.find('tbody').findAll('td', attrs={'data-title': 'G' ,'class': 'responsive'})[row].contents[0] 
     goals_scored.apppend(goals) 
     a = player_soup.find('tbody').findAll('td', attrs={'data-title': 'A'})[row].contents[0] 
     assists.append(a) 
    except: 
     pass  

player_data = {'player_name':player_name, 
'club':club, 
'position' : position, 
'goals_scored' : goals_scored, 
'assists' : assists, 
} 

df = pd.DataFrame.from_dict(player_data,orient='index') 

df 

Das einzige, was ich herausfinden kann, ist, dass es ein kleiner Unterschied in dem HTML-Code für die Variablen keine Daten zurück. Muss ich die Klasse = responsive in meinen Code aufnehmen? Wenn ja, irgendwelche Beispiele dafür, wie das aussehen könnte?

Position HTML: F

Tore HTML: 11

Einsicht

Antwort

0

Sie können versuchen, gelesen haben sollte wie folgt auf Ihre gewünschten Daten zu erhalten. Ich habe nur den Teil analysiert, den du brauchst. Der Rest, den Sie für den Datenrahmen tun können. Zu Ihrer Information, es gibt zwei Arten von Klassen, die an verschiedene td-Tags angehängt sind. odd und even. Vergessen Sie nicht, auch das zu berücksichtigen.

from bs4 import BeautifulSoup 
import requests 

page_url = "https://www.mlssoccer.com/stats/season?page={0}&franchise=select&year=2017&season_type=REG&group=goals" 
for url in [page_url.format(p) for p in range(5)]: 
    soup = BeautifulSoup(requests.get(url).text, "lxml") 
    table = soup.select("table")[0] 
    for items in table.select(".odd,.even"): 
     player = items.select("td[data-title='Player']")[0].text 
     club = items.select("td[data-title='Club']")[0].text 
     position = items.select("td[data-title='POS']")[0].text 
     goals = items.select("td[data-title='G']")[0].text 
     assist = items.select("td[data-title='A']")[0].text 
     print(player,club,position,goals,assist) 

Teilergebnis wie folgt aussieht:

Nemanja Nikolic CHI F 24 4 
Diego Valeri POR M 21 11 
Ola Kamara CLB F 18 3 

Da ich sowohl die Klassen in meinem Skript enthalten haben, so dass Sie alle Daten von diesem Standort erhalten.

+0

Danke für Ihre Eingabe und Zeit. Das funktioniert perfekt. Ich mag, wie Ihre Lösung den Code verdichtet und vereinfacht. Ich war mir des Problems mit .odd und .even Tags nicht bewusst, also danke für den Zeiger! –

0

Dies geschätzt wird, ist die Art, wie ich es tun würde:

import sys 
from bs4 import BeautifulSoup as bs 
import urllib2 
import datetime as dt 
import time 
import pandas as pd 

proxy_support = urllib2.ProxyHandler({}) 
opener = urllib2.build_opener(proxy_support) 

player_name=[] 
club =[] 
position = [] 
goals_scored = [] 
assists = [] 

for p in range(5): 
    player_url = 'http://www.mlssoccer.com/stats/season?page={p}&franchise=select&year=2017&season_type=REG&group=goals'.format(p=p) 
    page = opener.open(player_url).read() 
    player_soup = bs(page,"lxml") 
    print >>sys.stderr, '[{time}] Running page {n}...'.format(time=dt.datetime.now(), n=p) 
    rows = player_soup.find('tbody').findAll('tr') 

    for row in rows: 
     name = row.find('td', attrs={'data-title': 'Player'}).text 
     player_name.append(name) 
     team = row.find('td', attrs={'data-title': 'Club'}).text 
     club.append(team) 
     pos = row.find('td', attrs={'data-title': 'POS'}).text 
     position.append(pos) 
     goals = row.find('td', attrs={'data-title': 'G'}).text 
     goals_scored.append(goals) 
     a = row.find('td', attrs={'data-title': 'A'}).text 
     assists.append(a) 

player_data = {'player_name':player_name, 
'club':club, 
'position' : position, 
'goals_scored' : goals_scored, 
'assists' : assists, 
} 

df = pd.DataFrame.from_dict(player_data,orient='index') 
print (df) 

Ausgänge:

      0   1    2    3 \ 
club      CHI   NYC   POR    ATL 
position     F   F    M    F 
assists      4   9   11    1 
player_name Nemanja Nikolic David Villa Diego Valeri Josef Martinez 
goals_scored    24   22   21    19 

Sie haben einen Tippfehler in

goals_scored.apppend(goals) 

es

goals_scored.append(goals) 
+0

Vielen Dank für Ihre schnelle Antwort. Das funktioniert auch! –

Verwandte Themen