Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 28, 2013 12:36:50

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Помогите ускорить скрипт. BeautifulSoup.

Здравствуйте. Вот сделал набросок, чтобы парсить результаты поиска из crate.io

from bs4 import BeautifulSoup
from urllib.request import urlopen
import bisect
site = 'http://crate.io{0}'
page = BeautifulSoup(urlopen(site.format('/?has_releases=on&q=django')))
table = []
while True:
    for result in page.find_all('div', attrs={'class':'result'}): # строка с именем пакета  и количеством загрузок
        count = result.find('span', attrs={'class':'count'}).string # загрузки
        count = int(count.replace(',', ''))
        package_name = result.find(attrs={'class':'package-name'}).string # имя пакета
        couple = [count, package_name]
        bisect.insort_right(table, couple) # добавляю в список через сортировку
    li = page.find('li', attrs={'class':'next'}) # строка с ссылку на след страницу
    print(li['class'])
    if 'disabled' in li['class']: break # если найден disabled, то это последняя страница - выход
    page = BeautifulSoup(urlopen(site.format(li.a['href']))) # перехожу на след страницу
table.reverse() # хочу видеть на первых позициях пакет с большим кол загрузок
for num, i in enumerate(table): print(num, i)

Но уж больно долго выполняется парсинг. Может что-то нужно убрать, добавить? Подключить еще какие-то модули?

P.S.: как пустые строки в коде сохранить?

Отредактировано buddha (Янв. 28, 2013 12:45:54)

Офлайн

#2 Янв. 29, 2013 04:50:55

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

Помогите ускорить скрипт. BeautifulSoup.

“Небольшого” ускорения можно добиться заменив тормозной urllib.request на requests, например.
Сортировка конечного результата вместо сортировки при вставке еще немного ускорит выполнение.

Вот так работает намного быстрее

from concurrent.futures import ThreadPoolExecutor
from concurrent.futures import as_completed
from operator import itemgetter
from queue import Queue
import requests
from lxml import html
SITE = "http://crate.io{}"
class IterableQueue(Queue):
    def __iter__(self):
        return iter(self.get, StopIteration)
    def close(self):
        self.put(StopIteration)
def page(url, page_queue, page_set):
    _page = html.fromstring(requests.get(url).text)
    for a in _page.cssselect("li.active ~ li a"):
        link = a.get("href")
        try:
            num = int(a.text)
            if num not in page_set:
                page_set.add(num)
                link = SITE.format(link)
                page_queue.put(link)
        except ValueError:
            if link == "#":
                page_queue.put(StopIteration)
    packages = []
    for item in _page.cssselect("div.result.row"):
        name = item.cssselect("a")[0].text
        count = item.cssselect("span.count")[0].text.replace(",", "")
        packages.append((name, count))
    return packages
if "__main__" == __name__:
    page_queue = IterableQueue()
    page_set = set()
    result = []
    page_queue.put("https://crate.io/?has_releases=on&q=django")
    with ThreadPoolExecutor(max_workers=8) as pool:
        results = [pool.submit(page, url, page_queue, page_set) for url in page_queue]
        for task in as_completed(results):
            result.extend(task.result())
    for name, count in sorted(result, key=itemgetter(1), reverse=True):
        print(name, count)



Отредактировано pyuser (Янв. 29, 2013 07:17:26)

Офлайн

#3 Янв. 29, 2013 16:38:18

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Помогите ускорить скрипт. BeautifulSoup.

Спасибо за пример. С потоками, очередями дела еще не имел…

Отредактировано buddha (Янв. 29, 2013 21:33:16)

Офлайн

#4 Март 20, 2013 12:24:44

lorien
От:
Зарегистрирован: 2006-08-20
Сообщения: 755
Репутация: +  37  -
Профиль  

Помогите ускорить скрипт. BeautifulSoup.

> Но уж больно долго выполняется парсинг. Может что-то нужно убрать, добавить? Подключить еще какие-то модули?

Выкинуть тормозной BeautifulSoup, использовать lxml.html модуль

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version