Форум сайта python.su
26
Подскажите ошибки новичка - я написал парсер открытых статистик счетчика liveinternet.ru
План был такой:
1. Заходим на главную liveinternet.ru/rating/ и собираем все категории
2. Проходим по каждой категории и собираем количество страниц с сайтами
3. Многопоточно проходим у каждой категории по каждой странице с сайтами с собираем ссылки на “public” статистики.
4. Многопоточно проходим у каждой категории по каждой “public” статистики и отбираем те, у которых открыта ссылка “по поисковым фразам”
Полного понимания как работает асинхронный grab spider не было, поэтому отказался от такой реализации.
# -*- coding: UTF-8 -*- import logging, threading, Queue, traceback from grab import Grab TH = 5 class MyClass(): def __init__(self): self.urls_open_li = {} self.urls_open_key = {} def get_cat(self): ''' Получаем список категорий с главной LI в список self.cat_li ''' self.cat_li = [] g = Grab() g.go('http://www.liveinternet.ru/rating/') path = ['//tr[@class="high cloud'+str(k)+'"]' for k in xrange(2,6)] for p in path: for cat in g.doc.select(p): self.cat_li.append(cat.select('.//td/a').attr('href')[8:].replace('/','')) def get_cat_url(self, cat_li=['banks']): ''' Получаем количество страниц в категории. В словаре self.li_urls для каждой категории (ключа) сопоставляется список URL'ов данной категории ''' self.li_urls = {} for c_l in cat_li: g = Grab() g.go('http://www.liveinternet.ru/rating/' + c_l + '/') number = int(g.doc.select('//td[@align="right"]')[1].select('.//a')[3].text()) self.li_urls[c_l] = ['http://www.liveinternet.ru/rating/'+c_l+'/index.html?page='+str(k) for k in xrange(1,number+1)] def listmerge(self, lstlst): all=[] for lst in lstlst: all.extend(lst) return all class LiOpenStat(threading.Thread): def __init__(self,queue): threading.Thread.__init__(self) self.queue = queue self.open_li = [] self.open_key = [] def run(self): while True: try: item = self.queue.get_nowait() except Queue.Empty: break try: self.worker(item) except Exception, detail: traceback.print_exc() self.queue.task_done() def worker(self, host): ''' По каждому URL из очереди находим открытые (public) счетчики ''' g = Grab() g.go(host) for site in g.doc.select('//td[@align="right"][@width="20"]//a'): if site.select('.//img').attr('src')[22:28] == 'public': self.open_li.append('http://www.liveinternet.ru' + site.attr('href')) class LiOpenKey(LiOpenStat): def worker(self, host): ''' У каждого public счетчика проверяем доступ по ссылке "по поисковым фразам" ''' g = Grab() g.go(host) if (g.doc.select('//a[@href="queries.html"]/font').exists() is False) and (g.doc.select('//a[@href="queries.html"]').exists() is True): self.open_key.append(host) def main(): my_li = MyClass() my_li.get_cat() my_li.get_cat_url(my_li.cat_li) #my_li.get_cat_url(['hi-end']) q = Queue.Queue() for key in my_li.li_urls: all_open_li = [] for url in my_li.li_urls[key]: q.put(url) for i in xrange(TH): t = LiOpenStat(q) t.start() all_open_li.append(t.open_li) q.join() my_li.urls_open_li[key] = my_li.listmerge(all_open_li) for key in my_li.urls_open_li: all_open_key = [] for url in my_li.urls_open_li[key]: q.put(url) for i in xrange(TH): tt = LiOpenKey(q) tt.start() all_open_key.append(tt.open_key) q.join() my_li.urls_open_key[key] = my_li.listmerge(all_open_key) print my_li.urls_open_key if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) main()
Отредактировано ajib6ept (Март 1, 2014 17:56:51)
Офлайн
253
Насколько я понимаю во всем вашем посте нет никакого вопроса. Собственно что вы хотите?
Отредактировано doza_and (Март 1, 2014 18:28:15)
Офлайн
26
Вопрос то вот какой (неявно был задан в первом предложении) - как я понимаю, в программировании новички (такие как я) пишут код не совсем правильно, допускают стилистические ошибки, затрудняющие понимание/чтение, а более опытные товарищи подсказывают как правильно, лучше решить ту или иную задачу. Мне нужны такие подсказки.
Кто за деньги или как лучше организовать на общественных началах рефакторинг кода?
Отредактировано ajib6ept (Март 1, 2014 18:47:11)
Офлайн
1. Прочитайте PEP-8
2. Посмотрите на ваш код и сделайте так, чтобы он удовлетворял рекомендациям PEP-8
С первого раза вы ничего не запомните в PEP-8, так что смотрите туда постоянно на протяжении нескольких месяцев. Вот, собственно, главная рекомендация.
А ещё, давайте переменным осмысленные имена. TH, c_l - фиговые имена.
path = ['//tr[@class="high cloud'+str(k)+'"]' for k in xrange(2,6)] for p in path:
for num in xrange(2, 6): path = '//tr[@class="high cloud%d"]' % num ....
int(g.doc.select('//td[@align="right"]')[1].select('.//a')[3].text())int(g.doc.select('//td[@align="right"][2]//a[4]').text()Отредактировано lorien (Март 3, 2014 17:17:53)
Офлайн