Pull to refresh

Comments 22

Предсказание: ниже появится скрипт на bash/wget, который все это делает в одну строку :)
И все же это не crawler, а site-specific downloader…
Как это сформулировать на красивом русском языке?
В слове «Crawler» ([ˈkrôlər]) нет звука «а».
Плюс много. Я написал «краулер» так как в таком виде это слово используется в рунете вообще и на этом сайте в частности. Тег краулер существовал на сайте до моего появления на нём.
А кто-нибудь пробовал делать подобные вещи модифицируя chromium? Такую программу будет чрезвычайно сложно вычислить.
Но зачем? Достаточно просто иметь реалистичный User-Agent (и, быть может, Referer) и большинство сайтов не смогут отличить вас от обычного пользователя.
Писать краулеры на регулярках в 21 веке как-то неприлично уже… Добавляют к div-у какой-нибудь класс или другой атрибут и оно у вас все валится.
Не вижу проблемы. Цель проги — скачать книгу ровно один раз. После того хоть потоп пусть хоть классы меняют, хоть адрес сайта меняют.
М… На XPath ваш код был бы короче, писать их проще (т.к. на странице может быть несколько div-ов и вычислять их правильной регуляркой — порой непростая задача), и можно было бы повторно использовать для скачивания соседней книги полгода спустя.

В таком виде это «как я единожды скачал конкретную книгу с конкретного сайта», в плане масштабирования на нужды широкой аудитории этот опыт будет вреден, т.к. предлагаемый подход неуниверсален и устарел.

Вы же для аудитории статью пишете, а не для себя!
Если из этого кода убрать комменты и вывод информации, он займёт 21 строку. Не вижу принципиальной разницы.
И вы можете привести пример рабочего кода, который сделает то же самое и будет лишён всех указанных вами недостатков?
Да, конечно.

Данный пример примерно такой же по длине как и ваш, но при этом он автоматически определяет количество страниц, может скачивать любую книгу по ID с этого сайта, не чувствителен к изменению структуры HTML, добавлению атрибутов в div-ы, изменению пробелов и т.п., автоматически разруливает кодировки входных и выходных страниц, корректно обрабатывая HTML Entity tags и прочие мелочи.

Серьезно не тестировал (ночь, жена ждет ко сну), но принцип, думаю, понятен.

# coding=utf-8
import codecs
from grab import Grab
from lxml import html

g = Grab()

BOOK_ID = '115980' # ID книги, которую нам нужно скачать
paragraphs= [] # Сюда будем складывать собранные параграфы
title = "" # Здесь разместим найденный заголовок книги

# Собираем контент
for i in xrange(1,1000): # 1000 есть бесконечно большое количество страниц, зак которое мы не должны выходить
    url = "http://profismart.ru/web/bookreader-%s-%s.php" % (BOOK_ID,i)
    g.go(url)
    print i
    if i == 1 or g.response.url == url:
        title = g.xpath_text("//h1")
        paragraphs.extend(g.xpath_list('//div[./text()]'))
    else:
        break


# Записываем в файл
with codecs.open("output.html",'w','utf8') as f:
    book_text = u"\r\n".join(html.tostring(p,encoding=unicode) for p in paragraphs)

    f.write("""
        <!DOCTYPE html>
        <html>
            <head>
                <title>%s</title>
                <meta charset="utf-8">
            </head>
            <body>
                <h1>%s</h1>
                %s
            </body>
        </html>
            """ % (title,title,book_text))
А в чём проблема с регулярками? Данная задача с их помощью решается достаточно легко.
Sign up to leave a comment.

Articles