#python #html #beautifulsoup
Вопрос:
Я пытаюсь получить основные данные с этого сайта
Я хочу получить фрейм данных (или любой другой объект, который облегчает жизнь) в качестве вывода с подзаголовками в виде имен столбцов и телом под подзаголовком в виде строк под этим столбцом.
Мой код приведен ниже:
from bs4 import BeautifulSoup
import requests
import re
url = "https://www.bankersadda.com/17th-september-2021-daily-gk-update/"
page = requests.get(url)
html = page.text
soup = BeautifulSoup(html,'lxml') #"html.parser")
article = soup.find(class_ = "entry-content")
headings = []
lines = []
my_df = pd.DataFrame(index=range(100))
for strong in article.findAll('strong'):
if strong.parent.name =='p':
if strong.find(text=re.compile("News")):
headings.append(strong.text)
#headings
k=0
for ul in article.findAll('ul'):
for li in ul.findAll('li'):
lines.append(li.text)
lines= lines [""]
my_df[k] = pd.Series(lines)
k=k 1
my_df
Я хочу использовать список «заголовки», чтобы получить имена столбцов фрейма данных.
Очевидно, что я не пишу правильную логику. Я также исследовал nextSibling, потомков и другие атрибуты, но я не могу понять правильную логику. Может кто-нибудь, пожалуйста, помочь?
Ответ №1:
Как только вы получите заголовок, используйте .find_next()
его для получения списка новостных статей. Затем добавьте их в список под заголовком в качестве ключа в словаре. Затем просто используйте pd.concat()
с ignore_index=False
from bs4 import BeautifulSoup
import requests
import re
import pandas as pd
url = "https://www.bankersadda.com/17th-september-2021-daily-gk-update/"
page = requests.get(url)
html = page.text
soup = BeautifulSoup(html,'lxml') #"html.parser")
article = soup.find(class_ = "entry-content")
headlines = {}
news_headlines = article.find_all('p',text=re.compile("News"))
for news_headline in news_headlines:
end_of_news = False
sub_title = news_headline.find_next('p')
headlines[news_headline.text] = []
#print(news_headline.text)
while end_of_news == False:
headlines[news_headline.text].append(sub_title.text)
articles = sub_title.find_next('ul')
for li in articles.findAll('li'):
headlines[news_headline.text].append(li.text)
#print(li.text)
sub_title = articles.find_next('p')
if 'News' in sub_title.text or sub_title.text == '' :
end_of_news = True
df_list = []
for headings, lines in headlines.items():
temp = pd.DataFrame({headings:lines})
df_list.append(temp)
my_df = pd.concat(df_list, ignore_index=False, axis=1)
Выход:
print(my_df)
National News ... Obituaries News
0 1. Cabinet approves 100% FDI under automatic r... ... 11. Eminent Kashmiri Writer Aziz Hajini passes...
1 The Union Cabinet, chaired by Prime Minister N... ... Noted writer and former secretary of Jammu and...
2 A total of 9 structural and 5 process reforms ... ... He has over twenty books in Kashmiri to his cr...
3 Change in the definition of AGR: The definitio... ... 12. Former India player and Mohun Bagan great ...
4 Rationalised Spectrum Usage Charges: The month... ... Former India footballer and Mohun Bagan captai...
5 Four-year Moratorium on dues: Moratorium has b... ... Bhabani Roy helped Mohun Bagan win the Rovers ...
6 Foreign Direct Investment (FDI): The governmen... ... 13. 2 times Olympic Gold Medalist Yuriy Sedykh...
7 Auction calendar fixed: Spectrum auctions will... ... Double Olympic hammer throw gold medallist Yur...
8 Important takeaways for all competitive exams: ... He set the world record for the hammer throw w...
9 Minister of Communications: Ashwini Vaishnaw. ... He won his first gold medal at the 1976 Olympi...
[10 rows x 8 columns]
Комментарии:
1. Большое спасибо. Работает как заклинание! Единственная часть, которую я не понял, — это последний раздел. В частности, строка —temp = pd.Фрейм данных({заголовки:строки}) Что спасается здесь, в темпе?
2. Он создает фрейм данных из 1 столбца. Имя столбца — «заголовки», а строки-это список «строк».
3. Эй, обнаружена проблема с кодом. Он извлекает только первую новость под каждым заголовком, а не все новости.
4. ах. Да, я понимаю, что ты имеешь в виду. Я просто отрабатывал твой код. Я это немного исправлю
5. @MRD, попробуй сейчас.