Как стать автором
Обновить

Комментарии 51

Хм… Но я не вижу, где там текст статьи. И гугл не позволил мне обнаружить другие xml, кроме такого же списка, но уже новостей. Тыкните, пожалуйста =)
Ну там и не будет текстов, но позволит сократить время на поиск актуальных страниц ;)
Эх, и опять без комментариев. Раньше комментарии были зачастую полезней самих статей.
Нашел еще такой url, с него вполне можно стянуть комментарии к статье. Сейчас займусь этим =)
Статьи с комментариями, сожмите каким-нибудь 7zip в хорошем формате и выложите где-нибудь, на левом dropbox-е или google drive.

Ну и совсем хорошо, если раз в месяц обновлять.
Поддерживаю. Хотелось бы иметь локальную базу Хабра. Уж больно много тут интересной информации.
Просто база комментариев вам вряд ли что даст — это сырые данные. Грубо говоря, там всего лишь текст комментария, указатели и метаданные об авторе. Здесь об этом написано подробнее. Вскоре я напишу статью, где сделаю маленький аналог СоХабра для удобного чтения базы статей и комментариев.
Теперь все есть. Осталось только документацию написать =)
Как юзать
image
И в принципе у вас уже есть база на 10к статей
Хабр, сделай api!

В статье же написано, что API есть?

Вот, что значит не поставить смайлик )

Скорее всего, он никак не документирован для внешней среды и может сломаться без предупреждения.

Давно хочу что-то подобное сделать. Иметь возможность скачивать сайты не в виде html страниц (как это делает teleport pro и подобные программы), а в некую базу (ту же sqlite), для которой можно написать GUI-оболочку. Т.е. в основном с ориентацией на форумы и обсуждения.
В инете есть множество ценной информации, представленной в крайне неудобном виде. Например гугл-группы обсуждения предложений в стандарт 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 потоками, если нет проксей в кармане. Кроме того, краулер нужен, чтобы «ходить» по вложенным ссылкам, здесь этого не требуется.
Кстати, было бы интересно сравнить скорость работы с пауком.
Для монополизации доступа потоков/процессов к ресурсу можно использовать multiprocessing.Queue

Работать с очередями предельно просто. У вас будет 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к статьей.
В период разделения на «Гиктаймс» и «Хабрахабр» — на гиктаймсе были все нечетные, а на хабре четные (или наоборот), теперь опять все в кучу.
Я делаю немного по другому. Скачиваю все нужные мне ссылки сайта. А потом уже парсю локально. Потом все скачанные html файлы архивирую, и в облако. Если мне нужны еще какие-то данные (например, время комментариев), я не заново скачиваю ссылки, а скачиваю архив из облака, и достаю нужные мне данные из локальных файлов, что многократно ускоряет получение нужных мне данных.
Я вот уже лет 6 паршу хабр (ссылка нa мой «аггрегатор» у меня в профиле, если кому интересно)
Одно мне не понятно — зачем вы целиком скачиваете статьи, если для вашей статистики достаточно парсить только «списочные» страницы (типа `/hub/programming/`)?
У вас в статистике же сам контент статей никак не используется?
профиль пуст
Ого, не ожидал что хабр другим пользователям как-то иначе мой профиль показывает.
Если что, не реклама: hbrscnr.club
Не открывается, передаём привет РКН и диджитал оцеану.
Ага, это еще со времен войны с телеграмом, на некоторых провайдерах до сих пор не работает :(
Моей основной целью было спарсить текст статьи с заголовком, чтобы позже любой мог сделать аналог СоХабра, все остальное было добавлено по принципу «Потому что есть». В первой версии вообще парсился только контент, название, автор и теги.
Главной фишкой СоХабра было еще то, что он парсил постоянно и сохранял даже удаленные статьи. Жалко что закрылся :(
/kek/нул с адреса API
Если всю спарсированную дату записать на CSV файл и затем после парсинга импортировать файл в базу данных, то все это дело будет медленнее чем варинт, где подключаешься к бд и имротируешь дату с помощью query?
Если делать в лоб — то запись сразу в базу будет медленнее, чем записать, а потом прочитать. Но, как уже выше указал justhabrauser, можно настроить бд и увеличить её скорость, и она, скорее всего, будет быстрее, чем чтение из папки с 500 тыс. файлов. Но я этого, пока что, не проверял и утверждать, что это истина, не могу.
Спасибо за ответ.

А какой топ статей по нахождению в закладках у пользователей?

Есть такой проект — Kiwix. Это коллекция дампов сайтов вроде Википедии и StackOverflow + оффлайновая читалка для них (в том числе в виде сервера). Они используют специальный формат для хранения контента, со сжатием и полнотекстовым поиском. Русскоязычная Википедия без картинок, например, весит всего несколько гигабайт. Если сделаете дамп Хабра и опубликуете его на их платформе — будет просто замечательно.

Да, это было бы замечательно, однако, как я понял, zim файл это коллекция сжатых html. Т.е. необходимо вновь парсить хабр и уже сохранять оригинальные html файлы.
Мне кажется более простая реализация многопоточности была бы через concurrent.futures чем через dummy. Проще отслеживать и обрабатывать кейсы которые упали по какой либо причине и пустить их на повтор, без записи в файл. Я бы рекомендовал всегда использовать в реквестах таймаут, во избежания залипания потоков.

Ну и если изначальная цель собрать все данные, то использование сайтмапа уже упоминали выше + писать данные не в файлы, а сразу в базу по мере получения. Это позволит значительно ускорить процесс, сделать предварительную обработку того какие ссылки уже есть в базе, и работать только с оставшимися.
Я бы использовал mongo, что бы вообще не разбирать данные json или postgres если SQL привычнее для работы, sqlite обычно получается более проблемным.

Ну и из простого занудства, почему файлы содержат в названии async если в код не асинхронный.
Про concurrent.futures спасибо, сейчас прочту.
Про базы — я не работал с другими, кроме mysql и sqlite. Позже посмотрю, может быть и имеет смысл перейти на другую.
Сайтмап — не увидел его сразу. Так же, там ссылка на последние статьи, полного вроде бы нет. Так что да, придется тратить время на 404 ошибку.
Насчет имени файлов — изменю :)
Спасибо за замечания.
Быстрая проверка сайтмапа — habr.com/sitemap/sitemap8.xml. Хранит статьи за 2008 год. Потому осмелюсь предположить, что он хранит все статьи а не только новые.
Топ 15 авторов

А rssbot — это человек? Или редакторы реально статей пишут больше, чем робот?

https://habr.com/ru/users/rssbot/
1,4к публикаций, но последняя — 28 августа 2013. Видимо, с тех пор у некоторых редакторов действительно накопилось ещё больше.

Почему все попытки спарить Хабр сводятся к тому, чтобы перебирать все айдишники статей? Ведь куда проще и удобнее воспользоваться такой штукой как sitemap.xml — там всегда все живые ссылки — бери и качай.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории