Я пытаюсь отсортировать даты по некоторым результатам на веб-сайте. Я нашел даты между тегами <span class = "f"
. К сожалению, я не могу извлечь такую информацию, используя приведенный ниже код. Я хотел бы спросить вас, что не так в коде и как я могу извлечь даты и отсортировать их по возрастанию/убыванию.
Что я уже сделал, так это собрал информацию (первые 20 результатов) с веб-сайта в массив. Массив urls[] собирает информацию (предложения), опубликованные в разные периоды (в пересчете на месяцы, дни, минуты...). Вы можете подумать о сообщениях на Facebook или результатах в Google.
urls=[]
for url in search(' " life " ', stop=20):
urls.append(url) # this creates a list of results (sentences. For each of them I would like to report the date when it was published)
soup = BeautifulSoup(url)
for url in urls:
url = soup.find_all('span', {'class':'f'})
# <span class = "f">2 days ago - </span>
print(url)
Я должен ожидать таких результатов, как, например,
"Yesterday I went out with my friends" 2 days ago the oldest result
"I played basketball for several years" 20 hours ago ....
.... 19 hours ago ....
.... 5 hours ago ....
...
для каждого предложения. Поэтому у меня должно быть два массива, один для предложений и один для их даты соответственно, чтобы построить их.
Необработанные данные:
введите описание изображения здесь
Не могли бы вы помочь мне с предложениями о том, как это сделать? Спасибо
Пожалуйста, приведите пример фактического содержания url
. Это как <span class = "f">2 days ago - sentence </span>
?
Я не имею в виду желаемый результат, я имею в виду необработанные данные, которые вы получаете от find_all()
.
Я просто добавил картинку, чтобы показать необработанные данные
Для этого требуется несколько шагов:
span
. Вы можете сделать это с помощью replace()
, split()
или использовать регулярные выражения.Вот рабочая реализация. Обратите внимание, что вы можете расширить его, чтобы также поддерживать минуты, месяцы и т. д.
elements = [
'<span class = "f">21 hours ago - </span>',
'<span class = "f">20 hours ago - </span>',
'<span class = "f">2 days ago - </span>',
'<span class = "f">1 day ago - </span>']
# extract the durations (eg. 21 hours ago) and store them in times list
times = [elem.replace('<span class = "f">','').replace(' - </span>','') for elem in elements]
# categorize the times into days and hours
days = [time for time in times if "day" in time]
hours = [time for time in times if "hour" in time]
# sort each category in reverse order
days.sort(reverse=True)
hours.sort(reverse=True)
# join categories into a string, such that each time is on a new line
output = '\n'.join(days) + '\n' + '\n'.join(hours)
print(output)
Выход:
2 days ago
1 day ago
21 hours ago
20 hours ago
Демо: https://repl.it/@glhr/55552138
Другой более масштабируемый подход заключается в использовании словаря для преобразования каждой длительности в определенное количество минут, сохранения этих числовых длительностей в отдельном списке и сортировки исходного списка строк на основе числового списка:
elements = [
'<span class = "f">21 hours ago - </span>',
'<span class = "f">20 hours ago - </span>',
'<span class = "f">2 days ago - </span>',
'<span class = "f">1 day ago - </span>']
# extract the durations (eg. 21 hours ago) and store them in times list
times = [elem.replace('<span class = "f">','').replace(' - </span>','') for elem in elements]
minutes_per_duration = {"hours": 60, "hour": 60, "minute": 1, "minutes": 1, "day": 1440, "days": 1440}
duration_values = []
for time in times:
duration = time.split(" ")[1] # eg. hours
number = int(time.split(" ")[0]) # eg. 21
minutes = minutes_per_duration[duration] # eg. 60 (for hours)
total = minutes * number # 21 * 60 = 1260
duration_values.append(total)
# sort times based on calculated duration values
output = '\n'.join([times for duration_values, times in sorted(zip(duration_values, times),reverse=True)])
print(output)
Выход:
2 days ago
1 day ago
21 hours ago
20 hours ago
В своем коде вы можете реализовать это так:
def durationSpansToSortedList(elements):
# extract the durations (eg. 21 hours ago) and store them in times list
times = [elem.replace('<span class = "f">','').replace(' - </span>','') for elem in elements]
minutes_per_duration = {"hours": 60, "hour": 60, "minute": 1, "minutes": 1, "day": 1440, "days": 1440}
duration_values = []
for time in times:
duration = time.split(" ")[1] # eg. hours
number = int(time.split(" ")[0]) # eg. 21
minutes = minutes_per_duration[duration] # eg. 60 (for hours)
total = minutes * number # 21 * 60 = 1260
duration_values.append(total)
# sort times based on calculated duration values
# return times as list
return [[times for duration_values, times in sorted(zip(duration_values, times),reverse=True)], duration_values]
urls=[]
for url in search(' " life " ', stop=20):
urls.append(url) # this creates a list of results (sentences. For each of them I would like to report the date when it was published)
spanElements = []
sentenceElements = []
for url in urls:
soup = BeautifulSoup(url, "html.parser")
spanElements.append(str(soup.find_all('span', {'class':'f'})[0]))
sentenceElements.append(url)
sortedDurations, duration_values = durationSpansToSortedList(spanElements)
print("Sorted durations:", sortedDurations,"\n")
sortedSentences = [sentenceElements for duration_values, sentenceElements in sorted(zip(duration_values, sentenceElements), reverse=True)]
print("Sorted sentences:", sortedSentences)
Комментарии не для расширенного обсуждения; этот разговор был перешел в чат.
Похоже, уже в порядке от самого старого к самому новому? Можете ли вы поделиться URL?