Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Во-первых, я начинающий программист.
Во-вторых давайте приступим.
Нужные нам библиотеки (вставляем в командную строку, либо в терминале или куда вам удобно):
pip install beautifulsoup4
pip install requests
pip install fake-useragent
Инициализируем модули в наш заранее созданный проект, т.е. файл с расширением py.
from bs4 import BeautifulSoup
import random
import json
import requests
import datetime
from fake_useragent import UserAgent
Создаем переменную с модулем fake_useragent, чтобы мы могли потом использовать для генерации user-agent:
ua = UserAgent()
Определяем заголовки (для того чтобы сервер сайта мог понять, как он должен отправить ответ, а также помогает серверу определить отправителя запроса)
headers = {
'accept': 'application/json, text/plain, */*',
'user-Agent': ua.google,
}
Создаем словарь, где будут храниться название и ссылка на каждую статью:
article_dict = {}
Создаем цикл для сбора со всех страниц, а не с одной (с 1 по 3, т.к. страниц с ссылками в день, как я понимаю всего 3).
for i in range(1, 4):
Указываем url c форматирование кода, где i - номер страницы, которое вставляться при каждом проходе цикла.
url = f'https://habr.com/ru/top/daily/page{i}/'
Отправляем get запрос на сайт, указывая в первом аргументе - переменную с url сайта, во-втором заголовки. Атрибут text, нужен чтобы получить текстовое содержанием html страницы.
req = requests.get(url, headers=headers).text
Теперь с помощью BeautifulSoup соберем весь html код страницы.
soup = BeautifulSoup(req, 'lxml')
Если попробовать вывести такой код с помощью print(soup), выведется весь html код страницы.
Далее, используя наш "soup" созданный в прошлом шаге, с помощью метода find_all собираем все ссылки с помощью тега "a" в первом аргументе, во-втором, с помощью F12, ищем класс у всех ссылок наших статей, как мы видим это - tm-article-snippet__title-link.
all_hrefs_articles = soup.find_all('a', class_='tm-article-snippet__title-link')
Класс указывается с нижним подчеркиванием, т.к. это ключевое (зарезервированное) слово в Python.
Создаем еще один цикл, где мы будем проходиться по всем статьям собранных в переменной all_hrefs_articles.
В теге "a" с классом "tm-article-snippet__title-link" находится еще один тег "span" c нашими именами ссылок, получим его с помощью метода find.
article_name = article.find('span').text # собираем названия статей
Теперь получим ссылку на статью, указываем что это f строка, и с помощью get запроса в скобочках получаем атрибут "href" - основной атрибут тега "a".
article_link = f'https://habr.com{article.get("href")}'
Получается ссылка, например: "https://habr.com/ru/company/tinkoff/blog/715604/"
Теперь указываем пару ключ - значение для названия и ссылку на статью (для нашего словаря):
article_dict[article_name] = article_link
Выходим из обоих циклов. С помощью конструкции "with open" создаем файл articles_ + дата и время создания файла с помощью модуля datetime, который мы импортировали, файл создаем с расширением .json (ну мне так удобнее), следующее мы указываем 'w', что означает, что нужно создать файл с таким-то названием и вписать следующий код, который мы укажем внутри файла, также указываем кодировку " encoding ='utf-8' ", чтобы файл мог отобразить русские символы.
with open(f"articles_{datetime.datetime.now().strftime('%d_%m_%Y')}.json", "w", encoding='utf-8') as f:
Создаем конструкцию try, except (если нет ошибок при парсинге, выводится try, если выводится ошибка при парсинге => except)
try:
except:
В try, мы "говорим", чтобы в json файл отправлялись данные, 1 - словарь с нашими статьями , 2 - имя файла, куда отправлять данные (в открытии файла мы указали в конце его как f, чтобы с ним можно было работать), 3 - отступы (я сделал 4 для удобства чтения, можно указать свое), 4 - экранирование ASCII символов, и следующей строкой вывод, что статьи успешно были получены.
print('Статьи были успешно получены')
В except, мы выводим, что статьи не удалось получить и нужно искать проблемы в коде.
print('Статьи были успешно получены')
В конечном итоге, должно получиться что-то похожее:
from bs4 import BeautifulSoup
import random
import json
import requests
import datetime
from fake_useragent import UserAgent
ua = UserAgent()
headers = {
'accept': 'application/json, text/plain, */*',
'user-Agent': ua.google,
}
article_dict = {}
for i in range(1, 4):
url = f'https://habr.com/ru/top/daily/page{i}/'
req = requests.get(url, headers=headers).text
soup = BeautifulSoup(req, 'lxml')
all_hrefs_articles = soup.find_all('a', class_='tm-article-snippet__title-link') # получаем статьи
for article in all_hrefs_articles: # проходимся по статьям
article_name = article.find('span').text # собираем названия статей
article_link = f'https://habr.com{article.get("href")}' # ссылки на статьи
article_dict[article_name] = article_link
with open(f"articles_{datetime.datetime.now().strftime('%d_%m_%Y')}.json", "w", encoding='utf-8') as f:
try:
json.dump(article_dict, f, indent=4, ensure_ascii=False)
print('Статьи были успешно получены')
except:
print('Статьи не удалось получить')