Комментарии 51
Ну и совсем хорошо, если раз в месяц обновлять.
И в принципе у вас уже есть база на 10к статей
В инете есть множество ценной информации, представленной в крайне неудобном виде. Например гугл-группы обсуждения предложений в стандарт C++. Еще несколько старых форумов, которые ценны информацией, но есть риск что они исчезнут ввиду того что сейчас там практически никого нет.
Кто нибудь знает, существуют ли библиотеки для С++ (более привычного мне языка) для удобного скачиваная и парсинга веб-контента?
Набор C++ библиотек с github, которыми лично пользовался, думаю поможет :)
Для парсинга html могу посоветовать:
1. github.com/google/gumbo-parser
2. github.com/lexborisov/myhtml
Для работы с json:
1.https://github.com/nlohmann/json
Для запросов:
1. github.com/whoshuu/cpr — обертка над libcurl
Для Python есть замечательный фреймворк Scrapy, который предназначен для написания веб-краулеров. Их коробки поддерживает многопоточность и прочие вкусные штуки.
Работать с очередями предельно просто. У вас будет 3 потока-поставщика контента, и 1 поток-потребитель, который и будет писать в базу или еще куда. Не требуется даже заморачиваться с блокировками.
from multiprocessing import Process, Queue
sentinel = -1
def creator(data, q):
"""
Creates data to be consumed and waits for the consumer
to finish processing
"""
print('Creating data and putting it on the queue')
for item in data:
q.put(item)
def my_consumer(q):
"""
Consumes some data and works on it
In this case, all it does is double the input
"""
while True:
data = q.get()
print('data found to be processed: {}'.format(data))
processed = data * 2
print(processed)
if data is sentinel:
break
if __name__ == '__main__':
q = Queue()
data = [5, 10, 13, -1]
process_one = Process(target=creator, args=(data, q))
process_two = Process(target=my_consumer, args=(q,))
process_one.start()
process_two.start()
q.close()
q.join_thread()
process_one.join()
process_two.join()
SQLite3 не хочет работать с более чем одним потоком
Внезапно!
Документацию почитать религия запретила?
На самом деле это древняя "фича" SQLite — он невыносимо реактивен в сравнении с другими RDB, но — только в одно лицо. При записи блокируется вся база, например.
Не факт.
Если Вы складываете все файлы в одну директорию, то через несколько тысяч файлов оно начнет жутко тормозить.
Прямая запись в SQLite может оказаться быстрее.
Это почему же? Современные файловые системы нормально работают с папками на несколько сот тысяч файлов, никаких замедлений не замечено (в Windows по крайней мере). Если конечно вы не считаете замедлением, например, отображение или сортировку списка файлов этой папки в проводнике ))
В Винде создание нового файла в папке со множеством файлов с похожими именами может замедляться из-за поведения по умолчанию, при котором создаются дополнительные DOS-совместимые имена файлов в формате 8.3 (8 символов имя файла + 3 символа расширение). Если файлы называются 000000001, 00000002 и т.д., то для DOS-имени системе придется перебирать все файлы папки, чтобы найти уникальное число для подстановки в укороченное имя файла (чтобы сохранить уникальность имен).
Это поведение можно отключить через fsutil behavior set disable8dot3 1
но тогда и время выполнения скрипта увеличится в разы
SQLite при commit ожидает подтверждение записи данных от диска, что является наиболее долгой операцией, поскольку упирается в физическое ограничение диска. Однако SQLite имеет возможность отказаться от этого, выполнив
pragma synchronous = 0
В вашем случае, я считаю такое вполне допустимым. Скорость вставки увеличится в разы.
Можно подкрутить кеш, отключить индекс при загрузке и прочее, чтобы вставлять со скоростью ~100K записей/сек, но зачем?
Проблему много-поточности можно решить так: http-читатели скидывают данные в буфер, а отдельный процесс, который монопольно пишет в SQLite, периодически данные оттуда забирает и сохраняет в базу.
Из ожидаемых 490 406 было скачано лишь 228 512 статей. Получается, что более половины(261894) статей на хабре было скрыто или удалено.
А вы учитывали, что номера статьей не совсем порядковые? Когда я в свое время планировал сделать дамп, тест показал, что Хабр периодически меняет нумерацию — в какие-то периоды статьям присваиваются четные номера, в другие — нечетные. Иначе говоря, в вашем случае верней было б сказать, что отсутствовало около 17к статьей.
Одно мне не понятно — зачем вы целиком скачиваете статьи, если для вашей статистики достаточно парсить только «списочные» страницы (типа `/hub/programming/`)?
У вас в статистике же сам контент статей никак не используется?
Если что, не реклама: hbrscnr.club
А какой топ статей по нахождению в закладках у пользователей?
Есть такой проект — Kiwix. Это коллекция дампов сайтов вроде Википедии и StackOverflow + оффлайновая читалка для них (в том числе в виде сервера). Они используют специальный формат для хранения контента, со сжатием и полнотекстовым поиском. Русскоязычная Википедия без картинок, например, весит всего несколько гигабайт. Если сделаете дамп Хабра и опубликуете его на их платформе — будет просто замечательно.
Ну и если изначальная цель собрать все данные, то использование сайтмапа уже упоминали выше + писать данные не в файлы, а сразу в базу по мере получения. Это позволит значительно ускорить процесс, сделать предварительную обработку того какие ссылки уже есть в базе, и работать только с оставшимися.
Я бы использовал mongo, что бы вообще не разбирать данные json или postgres если SQL привычнее для работы, sqlite обычно получается более проблемным.
Ну и из простого занудства, почему файлы содержат в названии async если в код не асинхронный.
Про базы — я не работал с другими, кроме mysql и sqlite. Позже посмотрю, может быть и имеет смысл перейти на другую.
Сайтмап — не увидел его сразу. Так же, там ссылка на последние статьи, полного вроде бы нет. Так что да, придется тратить время на 404 ошибку.
Насчет имени файлов — изменю :)
Спасибо за замечания.
Топ 15 авторов
А rssbot — это человек? Или редакторы реально статей пишут больше, чем робот?
https://habr.com/ru/users/rssbot/
1,4к публикаций, но последняя — 28 августа 2013. Видимо, с тех пор у некоторых редакторов действительно накопилось ещё больше.
Весь Хабр в одной базе