Условные аргументы для извлечения данных из HTML

#python #html

Вопрос:

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

  1. Извлеките имена игроков из первого href тега
  2. найдите следующий тег с именем flaggenrahmen и извлеките данные в alt
  3. Если flaggenrahmen повторится еще раз, пропустите.
  4. Повторите шаги.

что я пробовал:

 player_dict = defaultdict(list) soup = BeautifulSoup(html) player_id = soup.select('*[href]') nation = soup.select('.flaggenrahmen') for l,k in zip(player_id, nation):  player_dict[l.get_text(strip=True)].append(k['alt'])  

Однако я не могу получить «пропуск» при flaggenrahmen повторении, и поэтому я получаю более одной страны на игрока.

Произведенная продукция:

 defaultdict(list,  {'': ['England', 'Spain', 'Portugal'],  'Trent Alexander-Arnold': ['Morocco'],  'Achraf Hakimi': ['England']})  

Ожидаемый результат:

 {'Trent Alexander-Arnold':['England'], 'Achraf Hakimi':['Morocco'], 'João Cancelo':['Portugal'], 'Reece James':['England']  }  

Вот данные html:

 html='''lt;tbodygt; lt;tr class="odd"gt; lt;td class="zentriert"gt;1lt;/tdgt;lt;td class=""gt;lt;table class="inline-table"gt;lt;trgt;lt;td rowspan="2"gt;lt;a href="#"gt;lt;img alt="Trent Alexander-Arnold" class="bilderrahmen-fixed" src="https://img.a.transfermarkt.technology/portrait/small/314353-1559826986.jpg?lm=1" title="Trent Alexander-Arnold"/gt;lt;/agt;lt;/tdgt;lt;td class="hauptlink"gt;lt;a class="spielprofil_tooltip" href="/trent-alexander-arnold/profil/spieler/314353" id="314353" title="Trent Alexander-Arnold"gt;Trent Alexander-Arnoldlt;/agt;lt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;Right-Backlt;/tdgt;lt;/trgt;lt;/tablegt;lt;/tdgt;lt;td class="zentriert"gt;23lt;/tdgt;lt;td class="zentriert"gt;lt;img alt="England" class="flaggenrahmen" src="https://tmssl.akamaized.net/images/flagge/verysmall/189.png?lm=1520611569" title="England"/gt;lt;/tdgt;lt;td class="zentriert"gt;lt;a class="vereinprofil_tooltip" href="/fc-liverpool/startseite/verein/31" id="31"gt;lt;img alt="Liverpool FC" class="" src="https://tmssl.akamaized.net/images/wappen/verysmall/31.png?lm=1456567819" title=" "/gt;lt;/agt;lt;/tdgt;lt;td class="rechts hauptlink"gt;lt;bgt;£67.50mlt;/bgt;lt;span class="icons_sprite red-arrow-ten" title="£90.00m"gt; lt;/spangt;lt;/tdgt;lt;/trgt; lt;tr class="even"gt; lt;td class="zentriert"gt;2lt;/tdgt;lt;td class=""gt;lt;table class="inline-table"gt;lt;trgt;lt;td rowspan="2"gt;lt;a href="#"gt;lt;img alt="Achraf Hakimi" class="bilderrahmen-fixed" src="https://img.a.transfermarkt.technology/portrait/small/398073-1633679363.jpg?lm=1" title="Achraf Hakimi"/gt;lt;/agt;lt;/tdgt;lt;td class="hauptlink"gt;lt;a class="spielprofil_tooltip" href="/achraf-hakimi/profil/spieler/398073" id="398073" title="Achraf Hakimi"gt;Achraf Hakimilt;/agt;lt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;Right-Backlt;/tdgt;lt;/trgt;lt;/tablegt;lt;/tdgt;lt;td class="zentriert"gt;22lt;/tdgt;lt;td class="zentriert"gt;lt;img alt="Morocco" class="flaggenrahmen" src="https://tmssl.akamaized.net/images/flagge/verysmall/107.png?lm=1520611569" title="Morocco"/gt;lt;br/gt;lt;img alt="Spain" class="flaggenrahmen" src="https://tmssl.akamaized.net/images/flagge/verysmall/157.png?lm=1520611569" title="Spain"/gt;lt;/tdgt;lt;td class="zentriert"gt;lt;a class="vereinprofil_tooltip" href="/fc-paris-saint-germain/startseite/verein/583" id="583"gt;lt;img alt="Paris Saint-Germain" class="" src="https://tmssl.akamaized.net/images/wappen/verysmall/583.png?lm=1522312728" title=" "/gt;lt;/agt;lt;/tdgt;lt;td class="rechts hauptlink"gt;lt;bgt;£63.00mlt;/bgt;lt;span class="icons_sprite green-arrow-ten" title="£54.00m"gt; lt;/spangt;lt;/tdgt;lt;/trgt; lt;tr class="odd"gt; lt;td class="zentriert"gt;3lt;/tdgt;lt;td class=""gt;lt;table class="inline-table"gt;lt;trgt;lt;td rowspan="2"gt;lt;a href="#"gt;lt;img alt="João Cancelo" class="bilderrahmen-fixed" src="https://img.a.transfermarkt.technology/portrait/small/182712-1615221629.jpg?lm=1" title="João Cancelo"/gt;lt;/agt;lt;/tdgt;lt;td class="hauptlink"gt;lt;a class="spielprofil_tooltip" href="/joao-cancelo/profil/spieler/182712" id="182712" title="João Cancelo"gt;João Cancelolt;/agt;lt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;Right-Backlt;/tdgt;lt;/trgt;lt;/tablegt;lt;/tdgt;lt;td class="zentriert"gt;27lt;/tdgt;lt;td class="zentriert"gt;lt;img alt="Portugal" class="flaggenrahmen" src="https://tmssl.akamaized.net/images/flagge/verysmall/136.png?lm=1520611569" title="Portugal"/gt;lt;/tdgt;lt;td class="zentriert"gt;lt;a class="vereinprofil_tooltip" href="/manchester-city/startseite/verein/281" id="281"gt;lt;img alt="Manchester City" class="" src="https://tmssl.akamaized.net/images/wappen/verysmall/281.png?lm=1467356331" title=" "/gt;lt;/agt;lt;/tdgt;lt;td class="rechts hauptlink"gt;lt;bgt;£49.50mlt;/bgt;lt;span class="icons_sprite green-arrow-ten" title="£45.00m"gt; lt;/spangt;lt;/tdgt;lt;/trgt; lt;tr class="even"gt; lt;td class="zentriert"gt;4lt;/tdgt;lt;td class=""gt;lt;table class="inline-table"gt;lt;trgt;lt;td rowspan="2"gt;lt;a href="#"gt;lt;img alt="Reece James" class="bilderrahmen-fixed" src="https://img.a.transfermarkt.technology/portrait/small/472423-1569484519.png?lm=1" title="Reece James"/gt;lt;/agt;lt;/tdgt;lt;td class="hauptlink"gt;lt;a class="spielprofil_tooltip" href="/reece-james/profil/spieler/472423" id="472423" title="Reece James"gt;Reece Jameslt;/agt;lt;/tdgt;lt;/trgt;lt;trgt;lt;tdgt;Right-Backlt;/tdgt;lt;/trgt;lt;/tablegt;lt;/tdgt;lt;td class="zentriert"gt;21lt;/tdgt;lt;td class="zentriert"gt;lt;img alt="England" class="flaggenrahmen" src="https://tmssl.akamaized.net/images/flagge/verysmall/189.png?lm=1520611569" title="England"/gt;lt;/tdgt;lt;td class="zentriert"gt;lt;a class="vereinprofil_tooltip" href="/fc-chelsea/startseite/verein/631" id="631"gt;lt;img alt="Chelsea FC" class="" src="https://tmssl.akamaized.net/images/wappen/verysmall/631.png?lm=1628160548" title=" "/gt;lt;/agt;lt;/tdgt;lt;td class="rechts hauptlink"gt;lt;bgt;£40.50mlt;/bgt;lt;span class="icons_sprite green-arrow-ten" title="£36.00m"gt; lt;/spangt;lt;/tdgt;lt;/trgt; lt;tr class="odd"gt; lt;tbodygt;'''.replace('lt; ', 'lt;')  

Ответ №1:

этого должно хватить

 players={} soup = BeautifulSoup(html, 'lxml') for el in soup.tbody.children:  if el.name!='tr':  continue  name=el.select_one('.spielprofil_tooltip')  country=el.select_one('.flaggenrahmen')  if name and country:  players[name.text]=[country['title']] print(players) gt;gt;gt; {'Trent Alexander-Arnold': ['England'], 'Achraf Hakimi': ['Morocco'], 'João Cancelo': ['Portugal'], 'Reece James': ['England']}  

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

1. Ах, это здорово! Но я, кажется, получаю следующую ошибку в строке 7: TypeError: 'NoneType' object is not subscriptable по какой-то причине ['title'] выдает мне ошибку. Когда я использую print(country) после этой строки, она печатает страны, но в конечном итоге я получаю ошибку.

2. это связано с тем, что предоставленный вами html-код не совпадает с тем, который вы действительно используете. я редактировал. это должно сработать, но это только предположение

3. Я получаю неверный синтаксис в строке 7

4. Мне удалось заставить его работать в моем случае в цикле for, используя ваш код. Хотя мне нравится твой ответ!

5. о боже, ты права, я идиотка. я отредактировал