Есть ли что-то для Python, подобное readability.js?

Я ищу пакет/модуль/функцию и т.д., что примерно соответствует эквиваленту Python для чтения Arc90.js

http://lab.arc90.com/experiments/readability

http://lab.arc90.com/experiments/readability/js/readability.js

чтобы я мог дать ему некоторый файл input.html, и в результате была очищена версия этой html-страницы " основной текст". Я хочу, чтобы я мог использовать его на стороне сервера (в отличие от JS-версии, которая работает только со стороны браузера).

Любые идеи?

PS: Я пробовал Rhino + env.js, и эта комбинация работает, но производительность неприемлема, для очистки большинства содержимого html требуется несколько минут:( (до сих пор не удалось найти, почему существует такая большая разница в производительности).

Ответы

Ответ 2

Мы только что запустили новый API обработки естественного языка на repustate.com. Используя REST API, вы можете очистить любой HTML или PDF и вернуть только текстовые части. Наш API бесплатный, поэтому не стесняйтесь использовать его для вашего сердца. И он реализован в python. Проверьте это и сравните результаты с readability.js. Я думаю, вы обнаружите, что они почти на 100% одинаковы.

Ответ 4

Я провел некоторое исследование этого в прошлом и закончил реализацию этого подхода [pdf] в Python. Последняя версия, которую я реализовал, также выполняла некоторую очистку до применения алгоритма, например удаление элементов head/ script/iframe, скрытых элементов и т.д., Но это было его суть.

Вот функция с (очень) наивной реализацией дискриминатора "link list", которая пытается удалить элементы с тяжелой ссылкой на текстовое соотношение (например, панели навигации, меню, объявления и т.д.):

def link_list_discriminator(html, min_links=2, ratio=0.5):
    """Remove blocks with a high link to text ratio.

    These are typically navigation elements.

    Based on an algorithm described in:
        http://www.psl.cs.columbia.edu/crunch/WWWJ.pdf

    :param html: ElementTree object.
    :param min_links: Minimum number of links inside an element
                      before considering a block for deletion.
    :param ratio: Ratio of link text to all text before an element is considered
                  for deletion.
    """
    def collapse(strings):
        return u''.join(filter(None, (text.strip() for text in strings)))

    # FIXME: This doesn't account for top-level text...
    for el in html.xpath('//*'):
        anchor_text = el.xpath('.//a//text()')
        anchor_count = len(anchor_text)
        anchor_text = collapse(anchor_text)
        text = collapse(el.xpath('.//text()'))
        anchors = float(len(anchor_text))
        all = float(len(text))
        if anchor_count > min_links and all and anchors / all > ratio:
            el.drop_tree()

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

Ответ 5

Почему бы не попробовать использовать Google V8/ Node.js вместо Rhino? Это должно быть приемлемо быстро.

Ответ 6

Я думаю, BeautifulSoup является лучшим парсером HTML для python. Но вам все равно нужно выяснить, что такое "основная" часть сайта.

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

Возможно, вы можете перенести подход readability.js к python?