Ответы пользователя по тегу Парсинг
  • Имеет ли юридическую силу запрет на парсинг сайта?

    @nirvimel
    Любые дополнительные юридические ограничения (сверх того, что требует государственное законодательство) можно навязать пользователю лишь одним способом - путем ДОБРОВОЛЬНОГО (с обеих сторон) заключения договора. Это обычно реализуется в виде пользовательского соглашения при регистрации на сайте. При этом одна сторона (сайт) обязуется предоставить какие-то услуги (например, доступ к некоторой информации), в то время как другая сторона (пользователь) добровольно принимает на себя какие-то ограничения (например, не пользоваться никакими автоматизированными средствами для извлечения, предоставляемой ему, информации). Это соглашения вступает в юридическую силу с момента нажатия на кнопку "Принимаю условия" (см. акцепт).
    Поскольку с анонимом в принципе невозможно заключить никакой договор (очевидно), то на, не прошедшего регистрацию пользователя, невозможно возложить никакие ограничения (сверх существующих в законе).

    Но все вышеописанное касается только СПОСОБА, которым пользователь взаимодействует с сайтом (автоматизированный/ручной/ножной/и.т.д.). Что касается самого контента, который пользователь потребляет, то на него распространяется все нормы авторского права (независимо от способа, которым он получен). Поскольку авторское право (как государственный закон и международное соглашение) распространяется на всех без исключения (в том числе и на анонимов), то не требуется заключать с пользователем никакого договора (и заставлять проходить регистрацию). Достаточно упомянуть (желательно на видном местом) запрет на использование данного контента в любых целях, кроме личного ознакомления. Это допустимо на основании того, что владелец исключительных прав на контент может определять любые ограничения на его использование. Что это дает: контент, собранный автоматизированными средствами, в дальнейшем не может быть использован никак без нарушения закона о защите авторских прав (это серьезнее, чем нарушение пользовательского соглашения). Это полный юридический тупик для того, кто захочет заняться парсингом (пусть даже само по себе это будет законно).
    Ответ написан
  • Как спарсить быстро много страниц в PHP?

    @nirvimel
    Тут поможет кеширование промежуточных результатов (после phpQuery) в БД. Если нужно выдавать всегда актуальные данные, при том что исходные данные постоянно меняются, то у каждой записи в кеше должна быть отметка времени записи, и если с того момента прошло больше N секунд/дней, то делается повторный запрос к исходной странице.

    Ну и выборка 500 страниц синхронно в одном потоке... если бы я увидел такой код в проекте, то подумал бы, что это сделано специально, чтобы разгрузить сервер для других задач или дать пользователю время сходить покурить.
    Ответ написан
  • Какие ссылки нужно использовать для яндекс-робота?

    @nirvimel
    Не глядя в код можно предположить, что вы в href каких-то ссылок забыли поставить слэш первым символом. То есть у вас где-то идет href="primer/index.html" вместо href="/primer/index.html". С вашей точки зрения кажется, что все работает нормально, ошибка незаметна, но бот резолвит такие относительные ссылки из документа /primer2/index.html в вот такие абсолютные ссылки /primer2/primer/index.html.

    P.S.: Вот что на самом деле обозначает это таинственное слово "primer", так часто встречающееся в примерах.
    Ответ написан
  • Какова реализация или советы по реализации чтения и поиск информации с сайта на c++ (Парсер)?

    @nirvimel
    1. Закачка страниц из сети при помощи libcurl.
    2. Разбор страниц в DOM при помощи libxml2 (или libxml++).
    3. Выборка интересующих элементов (ссылки, картинки, и.т.д.) при помощи XPath запросов к DOM.
    4. Многопоточность: заброс новых ссылок в общую очередь + пул потоков, выбирающих себе задания из этой очереди и отрабатывающих по пунктам 1, 2, 3.

    так как некоторые ссылки могут быть скриптами или css

    С этим нет никакой проблемы. XPath //a выбирет только реальные ссылки на страницы, по которым возможно перейти.
    Ответ написан
  • Как пасить сайт в котором контент выводиться с задержкой?

    @nirvimel
    Существует такая вкладка в Network в Developer Tools в браузере, там отображаются все сетевые запросы исходящие с активной страницы. Смотрите что запрашивается в момент перед погрузкой основного контента. Переписываете этот запрос на Python. Все!
    Единственное, иногда для корректной работы AJAX могут потребоваться куки с основной страницы. Тогда делаете requests сессию запрашиваете основную страницу (сама она не понадобиться), после чего в той же открытой сессии выполняете нужный AJAX.
    Ответ написан
  • Как осуществить логин на сайте?

    @nirvimel
    куки, может они как-то связаны с логином?

    А то!

    Смотрите что отправляет браузер в момент логина включая все заголовки, все куки, все тело POST и все параметры в нем (не что он должен отправлять исходя из структуры формы, а что в этот момент на самом деле отправляют скрипты) и сравнивайте с тем, что отправляет ваш парсер.
    Бывает, проще прочесть скрипты, понять их логику и переписать на питон. Бывает наоборот, обфусцированный скрипт на несколько тысяч строк, тогда проще анализировать сетевую активность в момент совершения действия (логина, например), пробовать разные варианты ввода, наблюдать как зависит передаваемое от введенного, выявлять закономерности и имитировать подобный алгоритм на питоне.
    Ответ написан
  • Как спарсить контент, который находится между двумя div'ами?

    @nirvimel
    XPath решает:
    //*[preceding-sibling::div[@class="start"] or self::div[@class="start"]][following-sibling::div[@class="end"] or self::div[@class="end"]]

    Но если начальный/конечный div-ы захватывать необязательно, то задача сильно упрощается:
    //*[preceding-sibling::div[@class="start"] and following-sibling::div[@class="end"]]
    Ответ написан
  • Как спарсить тег с плавающим расположением?

    @nirvimel
    PHP Simple HTML DOM Parser тут бессилен.
    А вот XPath легко решает проблему:
    //div[@class='primer']/p[@class='oposit part1 part2' and text()='Примечание']/following-sibling::div[@class='halfM indPar']/text()
    Ответ написан
  • Как грамотно обозвать строку-сепаратор, которая используется для разделения разных сущностей в текстовых форматах типа "ключ-значение"?

    @nirvimel
    Я думаю, marker будет правильным словом.
    Это слово не редко встречается в контексте data format.
    Релевантные результаты со словом boundary найти сложнее.

    Маркер, выделяющий какой-то раздел будет, вероятно, section marker

    Например, можно назвать идентификаторы section_begin_marker и section_end_marker.
    Ответ написан
  • Почему Python не сохраняет в excel так как надо?

    @nirvimel
    for post in list_doc.cssselect('.forum-post-table'):
        user = post.cssselect('.forum-user-name a')[0]
        name = user.text_content()
        url = urljoin(URL, user.get('href'))
        # title = user_name.get('title')
        descr = post.cssselect('.forum-post-text')[0].text_content()

    Набросал на коленке. В бою не проверял. Если даже остались какие-то ошибки, то, надеюсь, суть я передал.
    Ответ написан
  • Как записать результат парсинга на python в бд?

    @nirvimel
    Советую изучить какую-нибудь ORM, например SQLAlchemy, чтобы не месить SQL вручную и не изобретать велосипеды.
    Ответ написан
  • Как выполнить действие после yield?

    @nirvimel
    try:
        while condition:
            yield something
    finally:
        db.close()

    И замените это
    except:
        continue
    на
    except StandardError:
        continue
    Ответ написан
  • Как выгрузить данные с Canvas-графика?

    @nirvimel
    Там в теле cfnindex есть такой кусок.
    <script class="code" type="text/javascript">
        //<![CDATA[
        $(document).ready(function () {
            $.jqplot._noToImageButton = true;
            var graph = ...

    Вот в этом graph все исходные данные.

    Ну а с растрового Canvas, конечно, прочесть ничего невозможно, после того как график уже отрендерен.
    Ответ написан
  • Как уникализировать текст?

    @nirvimel
    Автоматические уникализаторы? Какая ностальгия... Но вы опоздали с этим лет на десять.
    Ответ написан
  • Парс выдачи Google, как обойти блокировку?

    @nirvimel
    1. Заголовки Accept и Accept-Language зависят от User-Agent. Вы меняете User-Agent, и Гугл может фиксировать это расхождение. Попробуйте для начала вместо getUseragent() задать константную строку. Потом, если вам так нужно менять User-Agent, то посмотрите как это делает Random Agent Spoofer, он согласут все заголовки с фейковым User-Agent, возможно придется лезть в его исходники, поэтому проще с константной строкой.
    2. Попробуйте еще убрать ru-RU из Accept-Language. Это не означает, что пропадут русскоязычные результаты в выдаче или будут проблемы с кодировкой. У меня вообще вся система и браузер не локализованы, это не мешает гуглить по-русски.
    3. https://www.google.ru/search?q=q&num=100 такие запросы шлют только боты. В браузере при поиске с главной страницы Гугала идет запрос огромной длинны с десятком параметров, в том числе, какие-то уникальные хэши. Попробуйте сначала запросить главную, принять и записать все cookies, выдрать из формы поиска url, по которому уйдет запрос, добавьте туда q=blabla и посылайте новый запрос со всеми cookie. Кстати, на каждый запрос приходят новые cookie и их бы неплохо использовать в следующем запросе, как бы это происходило в реальном браузере, это увеличит время/количество_запросов до бана.
    4. Не запрашивайте сразу num=100, вам так проще парсить, а Гуглу так проще банить тех, кто парсит. Уберите этот параметр и выкачивайте SERP по одной странице. Между запросами делайте паузы в несколько секунд как серфил бы живой человек. При этом возможно параллельно работать с другим запросом из другой сессии с другим набором cookies и User-Agent, как будто несколько человек сидят с одного IP из-за NAT. Но, вообще, выборка SERP глубже одной-двух страниц сильно увеличивают подозрение в ваш адрес и приближают капчу, постарайтесь по возможности вообще отказаться от выборки 100 результатов ради того чтобы парсер работал хоть как-то.
    5. Перед тем как делать все это, запустите Wireshark и сравните в нем вживую два запроса: один из браузера, другой от вашего скрипта в его текущей реализации, возможно какие-то различия бросятся в глаза сразу.
    6. Даже при соблюдении всех условий, бан неизбежен рано или поздно, это зависит от объемов трафика, который вы создаете с одного IP. С этим уже ничего не сделать. Спасет только большой пул проксей.
    Ответ написан
  • Какую выбрать тактику получения картинки логотипа компании?

    @nirvimel
    С точностью в 100% решить эту задачу в принципе невозможно, хотя бы потому, что логотипа может просто не быть в общем доступе или где-то существует соответствующая картинка, никак не помеченная.
    Но можно попробовать варианты:
    • Поиск по Википедии (eng). Там во многих статьям о компаниях приведен логотип. Причем это изображение допускается свободно копировать куда угодно.
    • Поиск по Гугл-картинкам по запросу < company_name >+logo. Например. Можно дополнительно отфильтровать по размеру или по типу.
    Ответ написан
  • Python парсинг сайта (характеристики)?

    @nirvimel
    from urllib.request import urlopen # for Python 3
    # from urllib2 import urlopen  # for Python 2
    
    from lxml.etree import XMLSyntaxError
    from lxml.html import fromstring
    from pandas import DataFrame, ExcelWriter
    
    URL = 'http://www.tinko.ru/c-3.html?limit=100&no_cache=true&p=l'
    ITEM_PATH = ' .info-block .product-name'
    DESCR_PATH = '.breadcrumb .active'
    
    HARET_PATH = '#techdata li'
    
    
    def parse_courses():
        f = urlopen(URL)
        list_html = f.read().decode('utf-8')
        list_doc = fromstring(list_html)
    
        df = DataFrame(columns=('name', 'description', 'href'))
    
        for elem in list_doc.cssselect(ITEM_PATH):
            a = elem.cssselect('a')[0]
            href = a.get('href')
            name = a.text
    
            details_html = urlopen(href).read().decode('utf-8')
    
            try:
                details_doc = fromstring(details_html)
            except XMLSyntaxError:
                continue
    
            description = details_doc.cssselect(DESCR_PATH)[0].text_content()
    
            haret_elems_list = [('name', name), ('description', description), ('href', href)]
    
            for haret_elems in details_doc.cssselect(HARET_PATH):
                spans = haret_elems.cssselect('span')
                title = spans[0].text_content()
                bower = spans[1].text_content()
                haret_elems_list.append((title, bower))
    
            df = df.append(dict(haret_elems_list), ignore_index=True)
    
        writer = ExcelWriter('tinko_ru_price_list.xlsx', engine='xlsxwriter')
        df.to_excel(writer, sheet_name='tinko.ru price list', header=True, index=False)
        writer.save()
    
    
    def main():
        parse_courses()
    
    
    if __name__ == '__main__':
        main()

    Вот вам готовый парсер tinko.ru с выгрузкой в Excel (проверял только в offline на странице с диска).
    Как теперь гонорар делить будем? ;)

    UPD: Подправлено.
    Ответ написан
  • XML to XML парсинг и конвертация. Как переделать структру?

    @nirvimel
    XSLT - Если хочется декларативно описыать преобразования.
    Если приятнее императивно, тогда просто руками на любом ЯП.
    Ответ написан