сегодня в 22:35

Привет, Хабр!
Решил посмотреть лучшие посты своего любимого хаба и с ужасом обнаружил, что такой фичи нет.
Когда это нас останавливало!
Прошу под кат всех желающих посмотреть на самые рейтинговые посты для каждого хаба + пару слов о реализации скрипта.
Скрипт написан на питоне при помощи отличной библиотеки grab, а точнее её модуля Spider. Спасибо автору(и по совместительству хаброюзеру) itforge за подробную документации.
В качестве БД использовалась sqlite3. Парсились только страницы хаба, т.е. в сам пост паук не залазил, что отразилось на скорости скрипта: получена информация о 111690 постах менее чем за час, и это в 1 поток.
from grab.spider import Spider, Task
import sqlite3 as lite
class HabraParser(Spider):
# отсюда начинаем парсить
initial_urls = ['http://habrahabr.ru/hubs/']
def prepare(self):
# сюда будем складывать
self.post = []
self.con = lite.connect('files/habra_hubs.db')
def task_initial(self, grab, task):
# стрелка, указывающая на следующую страницу списка хабов
nav = grab.doc.select('//ul[@class="next-prev"]/li/a[@class="next"]')
# парсим хабы и передаём ссылки в новое задание hub
for elem in grab.doc.select('//div[@class="info"]/div[@class="stat"]/a[2]'):
self.add_task(Task(name='hub', url=elem.attr('href')))
# если стрелка существует - переходим на следующую страницу
if nav.exists():
self.add_task(Task(name='initial', url=nav.attr('href')))
def task_hub(self, grab, task):
nav = grab.doc.select('//a[@class="next" and @id="next_page"]')
# парсим пост
for elem in grab.doc.select('//div[@class="post shortcuts_item"]'):
comments = ''
score = ''
post_url = elem.node.find('h1[@class="title"]/a').get('href')
post_title = elem.node.find('h1[@class="title"]/a').text
# Страховка от факапов
try:
comments = int(elem.node.find('.//span[@class="all"]').text)
except:
comments = 0
try:
score = int(elem.node.find('.//span[@class="score"]').text)
except:
score = 0
self.post.append([
score,
comments,
post_url,
post_title
])
if nav.exists():
self.add_task(Task(name='hub', url=nav.attr('href')))
else:
# сохраняем в бд
hub = task.url.split('/')[4] # название для таблицы
self.save_data(hub)
def save_data(self, hub):
with self.con:
self.cur = self.con.cursor()
self.cur.execute("DROP TABLE IF EXISTS %s"%hub)
self.cur.execute("CREATE TABLE %s(Score INT, Comments INT, Url TEXT, PostTitle TEXT)"%hub)
self.cur.executemany("INSERT INTO %s VALUES(?, ?, ?, ?)"%hub, self.post)
self.post = []
Дальше остаётся только задавать вопросы бд вида:
("SELECT * FROM %s ORDER BY Score DESC LIMIT 10" % hub)
Для этого был тоже написан простенький скриптик, который и сгенерировал большую часть этой статьи.
Первоначально была идея поместить ещё самые комментируемые посты(и для этого всё реализовано), но уж слишком толстой получается эта статья!
Хабы брались из условия:
habraindex > 100.0 and posts_number > 200
Бд, исходники и проч на гитхабе.
Ну а теперь самое интересное. Я думаю каждый найдёт себе что-нибудь по вкусу.
Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.
This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers.
Комментариев нет:
Отправить комментарий