Парсинг Habr (Python + LxmlSoup)
Только начал пробовать в парсинг, решил сделать бота, который присылает список статей.
Тут я собираю заголовки и ссылки на последние статьи:
from LxmlSoup import LxmlSoup
import requests
html = requests.get('https://habr.com/ru/articles/').text
soup = LxmlSoup(html)
links = soup.find_all('a', class_='tm-title__link')
for i, link in enumerate(links, start=1):
print(f'{i}: {link.text()}')
print('https://habr.com' + link.get('href'), '\n')
Теперь вопросы:
- Как ограничить парсинг до 3-5 результатов? Чтобы он не всю страничку собирал, а только новые 3-5 статей (они на хабре упорядочены).
- Как получить время публикации статьи? Рядом с заголовком на хабре пишется "55 минут назад", хочу записывать конкретное время (чтобы собрать статистику, типа "В четверг среднее время публикации статьи - 40 минут")
- Где и ЧТО почитать про html - с трудом понимаю какие теги надо искать и как из них доставать информацию.
Если что задачи несут исключительно учебный характер.
Ответы (2 шт):
Первый вопрос:
"Как ограничить парсинг до 3-5 результатов?"
magic_numbers = (13, 42, 54, 32, 12, 144)
for i, item in enumerate(magic_numbers, 1):
if i > 5:
print('Больше 5-ти элементов нам не надо, прерываем цикл.')
break
print(''.join(('Обработали:\n- первый элемент'.__mul__(i==1),
'- второй элемент'.__mul__(i==2),
'- третий элемент'.__mul__(i==3),
'- четвёртый элемент'.__mul__(i==4),
'- пятый элемент'.__mul__(i==5),)
)
)
output:
Обработали:
- первый элемент
- второй элемент
- третий элемент
- четвёртый элемент
- пятый элемент
"Больше 5-ти элементов нам не надо, прерываем цикл."
Второй и третий вопрос:
В браузере выделяете мышкой нужный контент и ПКМ вызываешь контекстное меню:
(может быть пункт: "исследовать элемент" - это зависит от браузера)
Дальше смотришь в каком теге нужные данные и смотришь родительские теги,
чтоб понять как выдернуть нужный контент.
- В
LxmlSoup
параметраlimit
для функцииfind_all()
, как я понял, нет, в отличие от его прародителя, BeautifulSoup. Так что стоит либо перейти наbs4
:
from bs4 import BeautifulSoup
import requests
html = requests.get('https://habr.com/ru/articles/').text
soup = BeautifulSoup(html, 'html.parser')
articles_limit = 5 # Изменить число статей на любое душе угодное
links = soup.find_all('a', class_='tm-title__link', limit=articles_limit)
for i, link in enumerate(links, start=1):
print(f'{i}: {link.text}')
print('https://habr.com' + link.get('href'), '\n')
либо парсить все статьи с помощью LxmlSoup
, а потом вывести лишь первые пять ссылок (если лишние статьи вам и для хранения в списке не нужны, можно воспользоваться срезкой):
...
articles_limit = 5
for i, link in enumerate(links[:articles_limit], start=1):
...
- Хабр не просто так помещает дату публикации в тег
<time>
с соответствующими ему атрибутами:
<time datetime="2024-08-24T12:36:58.000Z" title="2024-08-24, 20:36">18 минут назад</time>
Можно вытянуть оттуда дату через атрибут либо datetime
, либо title
, смотря, с каким форматом вам проще работать:
# В качестве примера взял код с bs4 выше
from bs4 import BeautifulSoup
import requests
html = requests.get('https://habr.com/ru/articles/').text
soup = BeautifulSoup(html, 'html.parser')
articles_count = 5
articles = soup.find_all('article', class_='tm-articles-list__item', limit=articles_count)
for i, article in enumerate(articles, start=1):
link = article.find('a', class_='tm-title__link')
date = article.find('a', class_='tm-article-datetime-published').find('time')
print(f'{i}: {link.text}')
print('https://habr.com' + link.get('href'))
article_datetime = date.get('datetime') # Либо date.get('title')
print(f'Время публикации: {article_datetime}', '\n')
- Если вы впринципе хотите почитать про то, какие есть элементы и для чего они нужны, рекомендую документацию MDN (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/) на английском (можно на русском, но переведено и перенесено не всё) или https://doka.guide/html/ на русском. Если вам нужно разобраться только с семантикой Хабра, открывайте DevTools и исследуйте всё, что вас интересует.