Очистка веб-страниц с использованием красивого супа (спортивные данные)

#python #web-scraping #beautifulsoup

#питон #соскабливание полотна #прекрасный суп

Вопрос:

Когда я пытаюсь загрузить этот код, я получаю две ошибки. 1: Первый из них заключается в том, что я не могу правильно очистить данные для name_text.

2: Я получаю ошибку отступа для team = name_text.div.text. Я знаю, что это, вероятно, легко решить, но я пробовал разные углубления, и, похоже, ничего не работает.

на веб-сайте я хочу наскрести название команды и коэффициенты.

 <div class="size14_f7opyze Endeavour_fhudrb0 medium_f1wf24vo participantText_fivg86r" data-automation-id="participant-one">Orlando Magic</div>
<div class="priceText_f71sibe"><span class="size14_f7opyze medium_f1wf24vo priceTextSize_frw9zm9" data-automation-id="price-text">5.85</span></div>
 

Приведенный выше HTML-код был скопирован с сайта.

 from bs4 import BeautifulSoup
from urllib.request import urlopen as uReq
my_url = 'https://www.sportsbet.com.au/betting/basketball-us'
uClient = uReq(my_url)
page_html = uClient.read()
uClient.close()

soup = BeautifulSoup(page_html, "html.parser")

price_text = soup.findAll("div",{"class":"priceText_f71sibe"})
name_text = soup.findAll("div",{"class":"size14_f7opyze Endeavour_fhudrb0 medium_f1wf24vo participantText_fivg86r"})
filename = "odds.csv"
f = open(filename,"w")
headers = "Team, odds_teamn"
print(name_text)
f.write(headers)

for price_text in price_texts:
team = name_text.div.text
odds = price_text.span.text

print(odds)
print(team   odds)
f.write(team   ","   odds   "n")
f.close()
 

Любая помощь была бы очень кстати. Ваше здоровье.

Ответ №1:

Ваш for loop отступ неверен. Правильный отступ будет:

 for price_text in price_texts:
    team = name_text.div.text
    odds = price_text.span.text
    team = name_text.div.text
    odds = price_text.span.text

    print(odds)
    print(team   odds)
    f.write(team   ","   odds   "n")
f.close()
 

С 4 пробелами перед командой и коэффициентами. Пожалуйста, ознакомьтесь с документацией Python ForLoop.

Кроме того, нет price_texts переменной. Вам нужно назначить его, когда вы выполняете findAll, вы забыли «S»:

 price_texts = soup.findAll("div",{"class":"priceText_f71sibe"})
 

Последнее, рассмотрите возможность использования with вместо open() и .close() для записи в ваш файл.

Комментарии:

1. Спасибо за комментарии. Теперь цикл приобретает больше смысла. Есть ли причина, по которой вы повторили team = name_text.div.text и odds = price_text.span.text? Я получаю сообщение об ошибке, когда добираюсь до строки team = name_text.div.text. В ошибке указано, что имя ‘name_text’ не определено, но я не понимаю почему, потому что я выполнил аналогичный процесс для коэффициентов, и он отлично работает для коэффициентов.

Ответ №2:

Я думал, что вы могли бы просто выполнить итерацию и сохранить их в списках, а затем записать в файл. К сожалению, я не могу получить доступ к сайту на работе, поэтому я не могу протестировать код, но я считаю, что это должно дать результат, который вы ищете:

 from bs4 import BeautifulSoup
from urllib.request import urlopen as uReq
import csv
from itertools import zip_longest

my_url = 'https://www.sportsbet.com.au/betting/basketball-us'
uClient = uReq(my_url)
page_html = uClient.read()
uClient.close()

soup = BeautifulSoup(page_html, "html.parser")

price_text = soup.findAll("span",{"data-automation-id":"price-text"})
name_text = soup.findAll("div",{"data-automation-id":"participant-one"})

team_list = [ name.text.strip() for name in name_text ]
odds_list = [ price.text.strip() for price in price_text ]

d = [team_list, odds_list]
export_data = zip_longest(*d, fillvalue = '')
with open('odds.csv', 'w', encoding="ISO-8859-1", newline='') as myfile:
      wr = csv.writer(myfile)
      wr.writerow(("Team", "odds_team"))
      wr.writerows(export_data)
myfile.close()
 

Комментарии:

1. Это намного выше моих возможностей, но работает без ошибок. Однако он не создает список названий команд. Заголовок 1 не имеет имен внизу, но заголовок 2 имеет шансы внизу.

2. ОК. Я исправлю это, когда приступлю к работе. Как я уже сказал, вы можете получить доступ к сайту. Убедитесь, что поиск для команд правильно отображает имена команд. Другая возможность заключается в наличии пробелов. Итак, я отредактирую это сейчас, но, как я уже сказал, немного углублюсь.

3. Глядя на OP, я бы, вероятно, предпочел использовать data-automation-id вместо class . Как я уже сказал, я немного исправлю код и объясню каждый бит, чтобы вы поняли, что он делает.

4. @mclo Я внес правку в код. попробуйте и посмотрите, что у вас получится

Ответ №3:

не могли бы вы попробовать это?

 from bs4 import BeautifulSoup
from urllib.request import urlopen as uReq
my_url = 'https://www.sportsbet.com.au/betting/basketball-us'
uClient = uReq(my_url)
page_html = uClient.read()
uClient.close()

soup = BeautifulSoup(page_html, "html.parser")

price_texts = soup.findAll("div",{"class":"priceText_f71sibe"})
name_texts = soup.findAll("div",{"class":"size14_f7opyze Endeavour_fhudrb0 medium_f1wf24voparticipantText_fivg86r"})
filename = "odds.csv"
f = open(filename,"w")
headers = "Team, odds_teamn"
print(name_text)
f.write(headers)

odds =''
team=''
for price_text in price_texts:
    odds = price_text.text
for name_text in name_texts:
    team = name_text.text
print(odds)
print(team   odds)
f.write(team   ","   odds   "n")
f.close()
 

Комментарии:

1. Это почти работает. Появляется ошибка NameError: имя ‘team’ не определено. Это та же ошибка, что и в ответе выше. Я в тупике. Этот проект слишком сложный для того, кто изучает базовый python.

2. мой плохой. вы должны определить команду и шансы перед циклами for. Я отредактировал его