Упорядочивание данных html, очищенных с помощью BeautifulSoup и Python

#python #web-scraping #beautifulsoup

#python #очистка веб-страниц #beautifulsoup

Вопрос:

Я хотел бы взять даты и списки наборов с этой страницы https://www.zappateers.com/fzshows/78.html а затем организуйте его так, чтобы он выглядел примерно так:

1978 08 26 Пурпурная лагуна

1978 08 26 Танцующий дурак

1978 08 26 Легкое мясо

1978 08 26 Дорогая, разве ты не хочешь такого мужчину, как я?

и т.д. таким образом, дата показа и сыгранная песня отображаются рядом друг с другом в столбцах.

У меня есть этот код на Python

 import requests
from bs4 import BeautifulSoup
source = requests.get('https://www.zappateers.com/fzshows/78.html').text
soup = BeautifulSoup(source, 'lxml')    

for heading in soup.find_all([ "h4", "p"]):
    
    print(heading.text.strip())
  

извлекается тег h4 (дата и место проведения) и тег p (setlists).

Но он просто выводит его следующим образом:

1978 08 26 — Festplatz Friedrichsau, Ульм, Германия Часть шоу была подготовлена, см. «Ein Leben als Extravaganza». «Пурпурная лагуна», «Танцующий дурак», «Легкое мясо», дорогая, разве ты не хочешь такого человека, как я?,

Что я могу сделать, чтобы упорядочить их по столбцам, как указано выше? Спасибо

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

1. Правильная ли ссылка? Он не будет загружаться для меня.

2. песни находятся в теге p с атрибутом class setlist . Однако есть даты с отсутствующими песнями, например, 1978 09 08, и это усложняет задачу. Нельзя просто перебирать поиск h4 , а затем p class=setlist теги

3. URL указан правильно. У меня это работает. У кого-нибудь еще есть проблемы?

4. Также обратите внимание на 1978 10 15, где у вас есть 3 p-тега с class=setlist, один для раннего показа и один для позднего показа

Ответ №1:

Это должно помочь вам:

 import requests
from bs4 import BeautifulSoup
import pandas as pd

source = requests.get('https://www.zappateers.com/fzshows/78.html').text
soup = BeautifulSoup(source, 'lxml')

text = []
dates = []

headings = soup.find_all('h4')

for index,p in enumerate(soup.find_all('p', class_ = "setlist")):
    h = headings[index]
    for x in range(len(p.text.strip().split(','))):
        if '-' in h.text:
            dates.append(h.text.strip().split('-')[0].strip())
    if '-' in h.text:
        text.append(p.text.strip().split(','))

text = [item for sublist in text for item in sublist]

df = pd.DataFrame([dates,text]).T
df.columns = ['Date','Title']
print(df)
  

Вывод:

            Date                                      Title
0    1978 08 26                          The Purple Lagoon
1    1978 08 26                               Dancin' Fool
2    1978 08 26                                  Easy Meat
3    1978 08 26        Honey Don't You Want A Man Like Me?
4    1978 08 26                            Keep It Greasey
..          ...                                        ...
462  1978 10 31                              Suicide Chump
463  1978 10 31                       Improvisations In Q*
464  1978 10 31               Why Does It Hurt When I Pee?
465  1978 10 31   Improvisations (incl. Hail Caesar Theme)
466  1978 10 31                              Magic Fingers

[467 rows x 2 columns]
  

Вы также можете отправить эти сведения в csv файл, добавив эту строку в свой код:

 df.to_csv('D:\Songs.csv',index = False)
  

Скриншот csv файла:

введите описание изображения здесь

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

1. Существует проблема с отсутствием <p calss=setlist> тега определенных дат, и это портит песни. например, распечатайте полный фрейм данных и посмотрите на 1978 09 08. Здесь показаны песни для 1978 09 09

2. Также обратите внимание на 1978 10 15, где у вас есть 3 p-тега с class=setlist, один для раннего показа и один для позднего показа

3. Большое вам спасибо! Работает отлично. Я пытался использовать df, но не смог определить разную длину массивов. Теперь у меня будет ваш код для изучения формы. Хотел бы я проголосовать за это не один раз. Еще раз спасибо

4. @Sushil привет — пытался решить некоторые проблемы. Когда тег <h4> использует class=»wrongdate», они втягиваются и портят списки песен.. (Я думаю, Буран упоминал об этом выше). Я изменил эту строку headings = soup.find_all(‘h4’) на headings = soup.find_all(‘h4’,class_= None), и это работает, когда URL zappateers.com/fzshows/72.html но не на оригинале выше. Другая проблема заключается в том, что есть тег h5 с надписью «Ранний показ» или «Поздний показ» и т. Д. Они не добавляются в массив. Я пытался заставить это работать, но с треском провалился. Помогите, пожалуйста?

5. Чтобы лучше проиллюстрировать, данные, которые я хочу очистить, выглядят следующим образом: <h4> ДАТА </h4> <ТИП h5 </h5> <Длина h6</h6> <p class=»setlist»>ПЕСНИ </p> Мне нужны только данные h4, h5 и p вфрейм данных. Не у каждого шоу есть тег h5, и, я думаю, это становится сложнее. Когда они отсутствуют, теги <h4> удаляются с неправильным содержимым <p>, поэтому песни из одного шоу добавляются в другое шоу.