2014-02-01 3 views
2

Я пытаюсь очистить некоторые спортивные данные с веб-сайта с помощью Beautifulsoup4, но у меня возникли проблемы с выяснением того, как действовать. Я не очень хорошо разбираюсь в HTML, и, похоже, не могу понять последний бит синтаксиса. После анализа данных я собираюсь подключить его к кадру данных Pandas. Я пытаюсь добыть домашнюю команду, гостиную и забивать. Вот мой код до сих пор:Python Beautifulsoup4 parsing

from bs4 import BeautifulSoup 
import urllib2 
import csv 

url = 'http://www.bbc.com/sport/football/premier-league/results' 
page = urllib2.urlopen(url).read() 
soup = BeautifulSoup(page) 

def has_class_but_no_id(tag): 
    return tag.has_attr('score') 

writer = csv.writer(open("webScraper.csv", "w")) 

for tag in soup.find_all('span', {'class':['team-away', 'team-home', 'score']}): 
    print(tag) 

вот пример вывода:

<span class="team-home teams"> 
<a href="/sport/football/teams/newcastle-united">Newcastle</a> </span> 
<span class="score"> <abbr title="Score"> 0-3 </abbr> </span> 
<span class="team-away teams"> 
<a href="/sport/football/teams/sunderland">Sunderland</a> </span> 

Мне нужно, чтобы сохранить команду (Newcastle), оценка (0-3), и команда гостей (Sunderland) в трех отдельных областях. По сути, я застрял, пытаясь извлечь «значение» из каждого тега и, похоже, не могу понять синтаксис в bs4. Мне нужно как tag.value, но все, что я нашел в документации, - tag.name или tag.attrs. Любая помощь или указатели будут очень благодарны!

ответ

2

Каждый блок оценки находится внутри элемента <td class='match-details'>, обводя его, чтобы извлечь сведения о матче.

Оттуда вы можете извлечь текст из дочерних элементов с помощью генератора .stripped_strings; просто передайте его ''.join(), чтобы получить все строки, содержащиеся в теге. Выберите team-home, score и team-away отдельно для простоты синтаксического анализа:

for match in soup.find_all('td', class_='match-details'): 
    home_tag = match.find('span', class_='team-home') 
    home = home_tag and ''.join(home_tag.stripped_strings) 
    score_tag = match.find('span', class_='score') 
    score = score_tag and ''.join(score_tag.stripped_strings) 
    away_tag = match.find('span', class_='team-away') 
    away = away_tag and ''.join(away_tag.stripped_strings) 

С дополнительным print это дает:

>>> for match in soup.find_all('td', class_='match-details'): 
...  home_tag = match.find('span', class_='team-home') 
...  home = home_tag and ''.join(home_tag.stripped_strings) 
...  score_tag = match.find('span', class_='score') 
...  score = score_tag and ''.join(score_tag.stripped_strings) 
...  away_tag = match.find('span', class_='team-away') 
...  away = away_tag and ''.join(away_tag.stripped_strings) 
...  if home and score and away: 
...   print home, score, away 
... 
Newcastle 0-3 Sunderland 
West Ham 2-0 Swansea 
Cardiff 2-1 Norwich 
Everton 2-1 Aston Villa 
Fulham 0-3 Southampton 
Hull 1-1 Tottenham 
Stoke 2-1 Man Utd 
Aston Villa 4-3 West Brom 
Chelsea 0-0 West Ham 
Sunderland 1-0 Stoke 
Tottenham 1-5 Man City 
Man Utd 2-0 Cardiff 
# etc. etc. etc. 
+0

ahh Я, должно быть, пропустил класс для матчей, спасибо! это именно то, что мне нужно. Я не знал, что могу повторить поиск в теге, используя .find. – flyingmeatball

1

Вы можете использовать tag.string propertyy, чтобы получить значение тега.

Для получения дополнительной информации обратитесь к документации. http://www.crummy.com/software/BeautifulSoup/bs4/doc/

+0

Я охотился по документации, но не может получить tag.string ценность для работы. Он возвращает «none» каждый раз. Если вы посмотрите на результат, в теге, который я возвращаю, есть еще один «тег». Есть ли способ установить Beautifulsoup для возврата тегов, только если он находится в другом теге? Например, выше, мне нужно будет продолжить поиск по тегу, но только если тег находится в теге span. – flyingmeatball