mydoc Documentation · 2019. 4. 2. · mydoc Documentation, Выпуск 1...

27
mydoc Documentation Выпуск 1 zlukfo 12 May 2016

Transcript of mydoc Documentation · 2019. 4. 2. · mydoc Documentation, Выпуск 1...

  • mydoc DocumentationВыпуск 1

    zlukfo

    12 May 2016

  • Оглавление

    1 Введение 11.1 Что такое парсинг . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Зачем нужен парсинг данных? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3 Алгоритм парсинга источников xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.4 Требования к программе-парсеру . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

    2 xmlPyParser. Быстрый старт 32.1 Анализ структуры источника xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32.2 Извлечение данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.3 Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

    3 Возможности парсера xmlPyParser 73.1 Базовые методы класса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73.2 Расширение класса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

    4 Расширенные методы парсера 11

    5 Приемы парсинга 135.1 Задание пути к данным в xml-источнике регулярным выражением . . . . . . . . . . . . . 135.2 Генератор адресов доступа к xml источнику данных . . . . . . . . . . . . . . . . . . . . . 13

    6 Парсинг базы вакансий 156.1 Алгоритм . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

    7 Парсинг удаленного источника (сайта) 177.1 Этап 1. Анализ сайта . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177.2 Этап 2. Анализ ссылок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187.3 Этап 3. Извлечение данных по нужным ссылкам . . . . . . . . . . . . . . . . . . . . . . . 20

    8 Источники открытых данных xml 218.1 Архивные данные для скачивания . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218.2 Online данные . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218.3 API сервисы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

    9 Примеры применения парсера 239.1 Получение списка городов и населенных пунктов РФ . . . . . . . . . . . . . . . . . . . . . 23

    i

  • ii

  • Глава 1

    Введение

    1.1 Что такое парсинг

    Парсинг - это извлечение необходимых данных и сохранения их в удобном виде для последующегоиспользования - поиска и анализа.

    XML - это формат хранения и представления данных, который очень широко используется в самыхразличных областях:

    • любые сайты Интернет (в том числе и этот) показывают Вам информацию, сохраненную в фор-мате xml

    • документы и электронные таблицы, с которыми Вы работаете на компьютере, электронные книгикоторые Вы читаете хранят данные в формате xml,

    • архивные статистическое данные госзакупок, биржевых котировок, научных исследований актив-но используют xml для хранения

    Ознакомиться со списком примеров полезных и интересных данных, хранящихся в формате xml можноздесь.

    1.2 Зачем нужен парсинг данных?

    Данные в формате xml удобно хранить, но не удобно регулярно использовать, т.е. регулярно выполнятьпоиск по коллекции данных, их преобразование и анализ. Для этого, необходимые данные извлекаютсяиз xml формата (парсятся) и сохраняются в более удобной форме, например, в базе данных.

    1.3 Алгоритм парсинга источников xml

    Многообразие сфер применения и востребованность формата xml обуславливают не прекращающую-ся разработку новых и улучшение существующих программ-парсеров - коммерческих и бесплатных,универсальных и созданных под конкретный тип данных.

    Независимо от того, какую программу-парсер Вы используете общий алгоритм парсинга формата xmlодинаков:

    1. анализируется структура источника xml в котором находятся нужные данные: определяются пу-ти доступа к данным - в каких узлах или атрибутах они хранятся, и их структура - данные

    1

  • mydoc Documentation, Выпуск 1

    являются неделимыми (атомарными) или составными, к какому типу они принадлежат- строко-вому, логическому, числовому,... Этот этап выполняется программой-парсером в полуавтоматиче-ском режиме. От набора инструментов, предлагаемых программой-парсером и удобства работыс ними зависят время, которое Вы затратите на анализ структуры xml и качество извлекаемыхпрограммой-парсером данных - их полноту и точность.

    2. непосредственно извлечение данных и их сохранение в формате, удобном для последующего по-иска, трансформации и анализа.Возможно, таким форматом будет база данных, а возможно -таблица Exel или что нибудь еще.

    1.4 Требования к программе-парсеру

    Практика работы с источниками данных xml помогла сформировать ряд практических требованийкоторым должна удовлетворять программа-парсер

    1. программа должна уметь извлекать данные из различных типов источников xml - как архивныхфайлов на компьютере, так и расположенных в сети: страниц сайтов, новостных лент, результатовAPI запросов и т.д..

    2. программа должна уметь извлекать данные из файлов большого размера. Многие полезные на-боры данных хранятся в файлах размером несколько гигабайт.

    3. программа должна иметь удобные инструменты для анализа xml источников с неизвестной струк-турой. Эти инструменты должны предоставлять информацию как в графическом так и консоль-ном вариантах.

    4. Настройка программы для извлечения данных должна быть максимально простой и не требоватьот пользователя углубленных знаний структуры xml формата. Т.е., для того, чтобы извлечьданные, Вам не нужно, например, знать, что такое xpath и как его применять.

    5. программа должна работать на компьютерах с различными операционными системами (windiws,*nix), быть нетребовательной к ресурсам системы (работать даже на маломощных компьютерах)и поддерживать как локальное так и удаленное управление

    6. Программа должна предоставлять инструменты для сохранения извлеченных данных во все вос-требованные форматы.

    К сожалению к моменту написания документации, программы-парсера, удовлетворяющей перечислен-ным требованиям мы не нашли, поэтому написали свою.

    Итак, представляем инструмент парсинга xml и html - xmlPyParser

    2 Глава 1. Введение

  • Глава 2

    xmlPyParser. Быстрый старт

    xmlPyParser - это программа написанная на языке программирования Python. xmlPyParser являетсяименно инструментом парсинга, потому что:

    • может быть запущен как конечное консольное приложение для анализа структуры xml источникаи извлечения данных из него.

    • может быть реализован как приложение с графическим (оконным) интерфейсом,

    • может быть импортирован в другие скрипты Python в виде класса,

    • может быть запущен на сервере в качестве Web-приложения.

    Мы постарались сделать использование парсера максимально простым и не требующим каких-либоглубоких и специальных знаний. Но некоторые вещи Вам все-таки знать необходимо.

    2.1 Анализ структуры источника xml

    Нужно знать

    1. Любой источник данных xml имеет древовидную структуру

    2. Все страницы любого сайта, которые Вы видите в своем браузере являются xml источникомданных, а точнее его подвида - html. А значит все что отображено на странице сайта -сохранено в древовидной структуре.

    3. Чтобы указать парсеру какие данные нужно извлечь, необходимо задать путь к этим дан-ным, начиная от корня дерева

    xmlPyParser предоставляет два способа определения пути к нужным данным: графический и кон-сольный.

    Графический способ наглядно отражает структуру всего дерева источника xml и позволяет быстроопределить путь к любым данным источника

    Пример_1 Необходимо отобразить структуру данных новостной ленты сайта Lenta.ru.Для этого просто введем команду

    xmlPyParser -getTree url='https://lenta.ru/rss'

    В результате парсер сгенерирует графический файл (png) наглядно отражающий структуру xml ис-точника

    3

  • mydoc Documentation, Выпуск 1

    Из рисунка легко понять, что в заданном источнике xml по пути rss/channel/description со-хранены данные ___, по пути rss/channel/item/description сохранены ___ а перейдя по путиrss/channel/item/pubDate мы узнаем дату и время появления новости

    Графический способ анализа структуры источника xml не удобен для сильно разветвленных источ-ников. К таковым прежде всего относятся страницы сайтов, сохраняющие данные в формате html.Например, вот так выглядит структура страницы сайта https://www.avito.ru, содержащая объявлениякупли-продажи

    Разобраться из рисунка, по какому пути находятся нужные дам данные (например, заголовок объяв-ления) практически невозможно.

    Поэтому, при определении пути к данным в сильно разветвленной структуре источника xml лучшевоспользоваться консольным способом. Поясним его работу на примере

    Пример_2 Необходимо узнать путь, по которому сохранены заголовки объявлений, отра-жающихся на страницах сайта Avito.ru

    Для этого открываем страницу сайта с объявлениями (регион не важен), берем первое попавшеесяобъявление и запоминаем что написано в его заголовке, например, “Багажник на крышу”

    Теперь запускаем xmlPyParser передав ему два параметра 1) адрес страницы сайта Avito.ru, на которомрасположены объявления, 2) текст заголовка объявления

    xmlPyParser -getPath url='https://www.avito.ru/rostov-na-donu' text='Багажник на крышу'

    Программа вернет примерно такой результат

    html/body/div/div/div/div/div/div/div/div/a

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

    Теперь, чтобы извлечь из страницы сайта заголовки всех объявлений, достаточно ввести команду

    4 Глава 2. xmlPyParser. Быстрый старт

    https://www.avito.ru

  • mydoc Documentation, Выпуск 1

    xmlPyParser -getData url='https://www.avito.ru/rostov-na-donu' path="html/body/div/div/div/div/div/div/div/div/a"

    2.2 Извлечение данных

    Нужно знать

    1. по одному и тому же пути дерева может находиться несколько элементов данных, имеющихразличное значение. Предыдущий пример наглядно это демонстрирует: извлекая значенияисточника по пути “html/body/div/div/div/div/div/div/div/div/a” мы получаем не один заго-ловок объявления (‘Багажник на крышу’ для которого мы определяли путь), а все заголовкиобъявлений расположенных на странице

    2. по своей природе, структуры данных xml и html сильно различаются: совокупность элемен-тов находящихся на одном уровне xml источника является набором данных одного типа. Вто же время, совокупность элементов, находящихся на одном уровне html следует, как пра-вило, рассматривать как набор данных, каждый из которых имеет свой уникальный тип.Поэтому при извлечении данных необходимо указывать тип источника данных (xml илиhtml). Проиллюстрируем сказанное на примере.

    Пример_3 Возьмем новостную ленту сайта http://inosmi.ru. Скорее всего, данные, со-хранены в данном источнике в формате xml (впрочем, как и у всех новостных лент).Запустим парсер для данного источника со следующими параметрами

    xmlPyParser -getData url='http://inosmi.ru/export/rss2/index.xml' path="rss/channel/item" source_type="xml"

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

    • title - заголовок новости

    • link - ссылка на новость

    • description - описание новости

    • guid - ___

    • pubDate - дата публикации

    • category - категория новости

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

    Пример_4 А теперь попробуем получить описание вакансий, размещенных на сайтеhttp://hh.ru.

    При помощи функции парсера getPath определяем, что путь для описания вакансий -“html/body/div/div/div/div/div/table/tr/td/div/div/table/tr/td/div/div/div/div/div”.

    Пробуем извлечь данные, находящиеся по данному пути

    xmlPyParser -getData url='https://rostov.hh.ru/search/vacancy?text=&area=76' path="html/body/div/div/div/div/div/table/tr/td/div/div/table/tr/td/div/div/div/div/div" source_type="html"

    В результате, помимо нужных нам данных парсер вернет много дополнительной информации, распо-ложенной по тому же пути html страницы.

    Для того, чтобы исключить вывод парсером ненужной информации задействуем атрибуты

    Нужно знать

    2.2. Извлечение данных 5

    http://inosmi.ruhttp://hh.ru

  • mydoc Documentation, Выпуск 1

    1. каждый элемент xml и html источника может иметь атрибуты. В парсинге атрибуты имеютдвойное назначение: а) они могут содержать значения уточняющие путь к необходимымданным, б) сами атрибуты могут содержать необходимые данные

    Узнать, какие атрибуты содержит каждый элемент источника по указанному пути

    xmlPyParser -getData url='https://rostov.hh.ru/search/vacancy?text=&area=76' path="html/body/div/div/div/div/div/table/tr/td/div/div/table/tr/td/div/div/div/div/div" source_type="html" attrib='*'

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

    Из полученных результатов видно, что элемент содержащий описание вакансии (см. условие примера4) имеет уникальный атрибут, которого нет у остальных элементов, находящихся по заданному путиимя атрибута ‘data-qa’, значение - ‘vacancy-serp__vacancy_snippet_responsibility’

    теперь нам осталось только уточнить путь, по которому парсеру необходимо извлекать данных изисходного источника

    А теперь проиллюстрируем, как извлечь необходимые данные, если их значения сохранены в атрибутахэлементов источника xml.

    Пример_6 В качестве источника возъмем ответ API сервиса геокодированияhttp://nominatim.openstreetmap.org. Если запустить парсер с такими параметра-ми

    xmlPyParser -getData url='http://nominatim.openstreetmap.org/search?q=Ростов&format=xml' path="searchresults/place" source_type="xml"

    то в результате мы получим пустые значения. Потому что вся информация хранится в атрибутахэлементов. А если мы запустим парсер с такими параметрами

    xmlPyParser -getData url='http://nominatim.openstreetmap.org/search?q=Ростов&format=xml' path="searchresults/place" source_type="xml" attib='display_name, lon, lat'

    то парсер извлечет из атрибутов 1) наименование найденной местности, 2) ее широту и долготу

    2.3 Резюме

    Итак, для извлечения данных с помощью xmlPyParser Вам необходимо выполнить несколько простыхшагов:

    1. Определяем адрес источника xml (путь к файлу на диске и адрес ресурса в Интернет) и типисточника (xml или html). Некоторые источники данных указаны здесь

    2. При помощи xmlPyParser узнаем пути доступа к нужным нам данным

    3. Запускаем парсер, указав ему путь к источнику xml (html) данных и пути к элементам источника,содержащем необходимые данные

    Протестировать базовый функционал программы xmlPyParser можно на сервере ___

    Ознакомиться со всеми возможностями парсера xmlPyParser можно здесь ___

    6 Глава 2. xmlPyParser. Быстрый старт

    http://nominatim.openstreetmap.org

  • Глава 3

    Возможности парсера xmlPyParser

    Ка было сказано в ___, xmlPyParser является инструментом парсинга xml источников данных,существует три способа его применения:

    • как пользовательского Python скрипта. Примеры данного способа приведены в ___

    • как Web приложения. Демо-версию можно протестировать здесь ___

    • как класса Python, импортируемого при написании собственных парсеров конкретных xml источ-ников.

    Последний способ позволяет реализовать все возможности xmlPyParser, описанию которых и посвя-щена данная статья.

    Прежде всего, следует запомнить, что класс xmlParser включает только базовые параметры и мето-ды необходимые для анализа и извлечения данных из любых xml источников. Но в мире нет ничегоуниверсального, и извлечение данных из конкретного xml источника имеет, как правило, свои осо-бенности. Поэтому, для удобной реализации прикладных задач xmlParser позволяет легко расширятьсвои возможности новыми методами и функциями, которые используя базовые, упрощают решениеконкретных задач.

    3.1 Базовые методы класса

    3.1.1 Создание объекта парсинга

    x=xmlParser(source_path=Source_Path, source_type=Source_Type)

    где:

    Source_Path путь к xml источнику данных (string).В качестве источника может бытьуказан путь к файлу или url адрес.

    Source_Type тип источника данных (string). Принимает значения ‘xml’ или ‘html’

    Если в качестве Source_Path задан url удаленного источника, для корректной работы с ним (анализаструктуры и извлечения данных) возможно потребуется задать заголовок в виде словаря. Делаетсяэто через присвоения необходимых значений свойству header

    x.header={'Accept': 'text/html', ...}

    Подробнее о значениях заголовков и их влиянии на корректность обращений к источнику данных черезurl можно прочитать здесь___

    7

  • mydoc Documentation, Выпуск 1

    3.1.2 Анализ структуры xml источника

    Как было сказано ранее __, анализ структуры необходим для определения путей, по которым в xmlисточнике сохранены нужные нам данные. xmlPyParser предоставляет два способа определения путей- консольный и визуальный. Иногда, для более точного определения пути рекомендуется использоватьих комбинацию.

    Чтобы определить путь к данным одного типа, используется 2 метода метод restorePathByData:

    1.

    x.restorePathByData(data_string=Text, in_attrib=Value):

    где:

    Text строка, содержащая значение (или часть значения) одного элемента нужных данных.

    Value логическое значение True или False, разрешающее или запрещающее поиск значенияText в атрибутах элемента источника данных.

    2.

    x.html.restorePathByAttrib(source_path='', tag_name='', attrib={}):

    где:

    source_path путь к источнику данных. Если не задан - берется путь при создании экзем-пляра

    tag_name имя тега в котором будем искать нужные атрибуты.

    attrib словарь атрибутов, однозначно определяющий тег, путо до которого нужно найти.

    Оба Метода возвращает строку-путь в источнике данных, по которому найдена заданная строка

    Чтобы оценить структуру источника данных целиком, лучше использовать графический способ. Де-лается это следующим образом - сначала вызывается метод getTree, который генерирует дерево ис-точника данных, затем это дерево сохраняется в файл одного из доступных графических форматовpng или svg

    x.getTree()x.saveTree2png() # для сохранения в файл pngx.saveTree2svg() # для сохранения в файл svg

    Каждый из приведенных в примере методов имеет необязательные атрибуты. Разберем их

    x.getTree(count=0, get_attrib=False)

    где:

    count Параметр полезен при построении дерева, если источник - xml файл боль-шого размера. Как правило, такие файлы имеют достаточно однородную структуру исодержат большой объем однотипных данных. А значит нет необходимости анализиро-вать весь файл, чтобы определить структуру источника. Достаточно проанализироватьпервые count элементов файла. Поэтому, для сокращения времени на построение дере-ва в качестве значения данного параметра передается целое число, указывающее, чтоанализ структуры следует прекратить после просмотра данного количества элементов.Значение count зависит от конкретного xml источника и подбирается эмпирически.

    get_attrib логическое значение True или False, разрешающее или запрещающее извлече-ние атрибутов из элементов источника при построении дерева.

    8 Глава 3. Возможности парсера xmlPyParser

  • mydoc Documentation, Выпуск 1

    Методы saveTree2png и saveTree2svg имеют одинаковые параметры

    x.saveTree2png(self, file_output=None, tree_type=True, width=1200, height=600):

    где:

    file_output имя выходного графического файла в котором будет сохранена структура ис-точника данных. Если имя файла не задано, парсер сгенерирует его автоматически.Файл сохраняется в папку расположения скрипта.

    tree_type логическая переменная, которая указывает в каком виде сохранять структуруисточника - в виде иерархического дерева (True) или в виде звезды (False)/ Первыйвариант более наглядный и легкий для восприятия, второй более компактный

    width, height размер рисунка графического файла в пикселях

    Для визуального отражения структуры источника в xmlPyParser существует еще один полезный методtoD3js(). Он преобразует структуру источника в структуру данных нотации treejson. Эта нотацияиспользуется популяроной javascript библиотекой D3js для отображения иерархических структур вбраузере. Метод вызывается без параметров и возвращает словарь структуры источника в форматеtreejson

    3.1.3 Извлечение данных из источника

    Для извлечения применяется метод getData()

    data=x.getData(Path_List, get_attrib=False, head=0, type_response=None):

    где:

    Path_List список путей к данным источника. Как правило, необходимые данные находят-ся в разных элементах источника xml, соответственно доступ к ним осуществляется поразным путям. Метод позволяет одновременно извлекать данные по нескольким путям,для этого их необходимо перечислить.

    get_attrib логическая переменная, которая указывает на необходимость извлечения (True)данных из атрибутов элементов, находящихся по указанным путям

    head параметр полезен при работе с файлами-источниками xml большого размера. Что-бы понимать, что пути к данным указаны правильно и извлекаются именно нужныенам данные, данному параметру нужно присвоить ненулевое значение. Тогда, послеизвлечения head элементов данных парсер прервет работу

    type_response Определяет способ трансформации данные перед их возвращением мето-дом. По умолчанию, парсер при нахождении очередной порции данных в источнике xmlтут же возвращает их в виде пары путь к элементу - значение элемента. Данные пара-метр, через присвоения ему значения ‘json’ позволяет перед возвращением очереднойпорции найденных данных предварительно преобразовать их по следующему сцена-рию: найденные данные будут накапливаться во внутреннем буфере до тех пор, покапути к ним не начнут повторятся. Как только это произойдет - данные будут возвра-щены одной порцией и парсер будет продолжать работу снова накапливая данные доих повторения. В данном случае, каждая порция возвращаемых данных эквивалентнастроке в таблице с несколькими полями

    3.1. Базовые методы класса 9

  • mydoc Documentation, Выпуск 1

    3.2 Расширение класса

    Базовый функционал xmlParser легко расширяется дополнительными методами с учетом спецификирешаемых задач. Для этого нужно сделать два шага

    1. создать новый класс-расширение, включающий необходимые методы

    2. добавить новый класс-расширение в базовый класс

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

    10 Глава 3. Возможности парсера xmlPyParser

  • Глава 4

    Расширенные методы парсера

    Парсер легко расширять дополняя его методами, решающими конкретные прикладные задачи. Дляэтого используется специальный класс ParserTools. Данный класс постоянно обновляется, его методыописываются в данном разделе.

    1. Получение всех ссылок текущей страницы сайта getLinks()

    Метод возвращает генератор списка всех ссылок страницы сайта, указанной при создании экземплярапарсера.

    2. Получение всех ссылок сайта, содержащих наборы необходимых данныхgetAllDataLinks(source_template=[])

    Метод рекурсивно обходит все страницы сайта и находит по указанному шаблону ссылки, на страницы,содержащие наборы необходимых данных. Шаблон ссылок задается списком регулярных выражений.

    11

  • mydoc Documentation, Выпуск 1

    12 Глава 4. Расширенные методы парсера

  • Глава 5

    Приемы парсинга

    В данной статье содержатся некоторые неочевидные приемы работы с парсером.

    5.1 Задание пути к данным в xml-источнике регулярным выра-жением

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

    Пример использования Необходимо с текущей страницы сайта извлечь все ссылки

    Решение

    Как известно, ссылки содержатся в атрибуте href тега a. Значит там необходимо выделить в источникевсе теги a с атрибутом href и извлечь все значения этих атрибутов. Делается это так

    x=xmlParser('http://www.cian.ru', 'html')for i in x.getData(['.*/a'], get_attrib=True):

    if i[1] and 'href' in i[1]:print i[1]['href']

    5.2 Генератор адресов доступа к xml источнику данных

    Наиболее часто потребность такого генератора возникает при извлечении данных из html источников- сайтов в Интернете.

    На одной странице сайта, как правило, хранится лишь небольшая порция информации. Чтобы собратьзначительный объем данных, парсеру необходимо обойти множество страниц сайта и извлечь данныеиз каждой. Так вот, генератор адресов является одним из способов указать сайту множество адресов,которые ему необходимо обойти, чтобы извлечь данные. Идея генератора основана на том, что адре-са на страницы с необходимыми данными имеют, как правило, одинаковую структуру и отличаютсялишь отдельными элементами. Например, объявления о продаже однокомнатной или двухкомнатнойквартиры в Москве сайта http://cian.ru находятся по адресу

    http://www.cian.ru/cat.php?deal_type=sale&engine_version=2&offer_type=flat&region=1&room1=1&room2=1

    о продаже аналогичных квартир в Санкт-Перербурге - по адресу

    http://www.cian.ru/cat.php?deal_type=sale&engine_version=2&offer_type=flat&region=2&room1=1&room2=1

    а в Ростове-на-Дону http://www.cian.ru/cat.php?deal_type=sale&engine_version=2&offer_type=flat&region=4606&room1=1&room2=1

    13

    http://cian.ruhttp://www.cian.ru/cat.php?deal_type=sale&engine_version=2&offer_type=flat&region=1&room1=1&room2=1http://www.cian.ru/cat.php?deal_type=sale&engine_version=2&offer_type=flat&region=2&room1=1&room2=1http://www.cian.ru/cat.php?deal_type=sale&engine_version=2&offer_type=flat&region=4606&room1=1&room2=1

  • mydoc Documentation, Выпуск 1

    Теперь практическая задача - указать парсеру адреса к спискам объявлений о продаже одно-, двух- ичетырехкомнатных квартир в Москве, Санкт-Петербурге и Ростовской области. С помощью генератораадресов это делается так:

    for link in ['http://www.cian.ru/cat.php?deal_type=sale&...&region=%(reg)s &room%(n)s =1' % {'reg':reg, 'n':n}for reg in ['1', '2', '4606']

    for n in xrange(1,5,1)]:print link

    14 Глава 5. Приемы парсинга

  • Глава 6

    Парсинг базы вакансий

    В данном разделе по шагам рассмотрен практический пример парсинга большого xml файла.

    Задача Необходимо закачать в таблицу БД Postgresql Общероссийскую ба-зу вакансий, сохраненную в формате xml и доступную по адресуhttp://data.gov.ru/opendata/7710538364-vacansii

    Исходные данные В распакованнном виде файл xml занимает 842,3 Мб.

    Полученные результаты

    • Количество полей таблицы - 19

    • Количество записей - 320 479

    • Общее время парсинга и закачки данных в таблицу БД Postgresql - 29 мин.

    6.1 Алгоритм

    1. Определяет структуру данных источника xml.

    В большинстве своем архивные файлы xml имеют не сильно разветвленную структуру и ассоциатив-ные имена тегов. Поэтому анализировать структуру данных в файлах рекомендуется графическимспособом.

    Поскольку наш файл имеет внушительный размер, очевидно, он содержит много записей одинаковойструктуры. Поэтому анализировать файл целиком для построения структуры данных не имеет смысла.Выполним построение структуры данных на примере первых 1000 элементов

    x=xmlParser('OBV_full.xml')x.getTree(count=1000)x.saveTree2svg(width=2000)

    Получили вот такую структуру.___

    Чтобы убедиться, что полученная нами структура является полной, повторим построение дерева, уве-личив количество тегов до 10000

    x=xmlParser('OBV_full.xml')x.getTree(count=1000)x.saveTree2svg(width=2000)

    Как видим, структура не изменилась. Зничит показанное на рисунке дерево полностью отражает струк-туру данных xml источника.

    15

    http://data.gov.ru/opendata/7710538364-vacansii

  • mydoc Documentation, Выпуск 1

    2. Указываем пути к данным

    Теги элементов xml файла имеют как правило информативные имена, поэтому из рисунка легко понятькакие данные хранит каждый элемент. Кроме того, по рисунку легко построить пути для каждогонужного элемента. В нашем примере мы будем извлекать данные из всех элементов

    path2Data=['source/vacancies/vacancy/company/name','source/vacancies/vacancy/company/hr-agency','source/vacancies/vacancy/company/descrip',

    'source/vacancies/vacancy/addresses/address/location','source/vacancies/vacancy/addresses/address/lng','source/vacancies/vacancy/addresses/address/lat',

    'source/vacancies/vacancy/requirement/education','source/vacancies/vacancy/requirement/qualification','source/vacancies/vacancy/requirement/experience',

    'source/vacancies/vacancy/creation-date','source/vacancies/vacancy/salary','source/vacancies/vacancy/currency','source/vacancies/vacancy/category/industry','source/vacancies/vacancy/job-name','source/vacancies/vacancy/employment','source/vacancies/vacancy/schedule','source/vacancies/vacancy/description','source/vacancies/vacancy/duty',

    ]

    3. Создаем генератор извлекаемых данных

    result=x.getData(path2Data, type_response='json')

    4. Сохраняем данные в таблицу БД

    import psycopg2conn = psycopg2.connect("dbname=vacancy user=admin password=123456")conn.autocommit=Truecur = conn.cursor()for rec in result:

    fields_name='('+', '.join(['"'+i.split('/')[-1]+'"' for i in rec.keys()])+')'templ='('+(ur'%s , '*len(rec))[:-2]+')'query= "INSERT INTO pub_simple %s VALUES %s " % (fields_name, templ)cur.execute(query, tuple(rec.values()))

    Вот и все! Все данные в нашей таблице.

    16 Глава 6. Парсинг базы вакансий

  • Глава 7

    Парсинг удаленного источника (сайта)

    Здесь мы рассмотрим пример парсинга интернет-сайта. Одним из наиболее популярных объектов пар-синга являются сайты относящиеся к одному из типов

    • интернет-магазины

    • сайты объявлений купли-продажи

    • сайты риэлтерских агентств

    Все они хранят большой объем данных соответствующей предметной области. А задача парсинга -извлечь эти данные и сохранить в удобном для последующего поиска и анализа виде. Адреса некоторыхтаких сайтов можно узнать здесь ___

    Поскольку в предыдущем примере мы извлекали данные из общероссийской базы вакансий, продол-жим данную тематику и рассмотрим пример извлечения данных из сайта популярного рекрутинковогоагенства HeadHunter ___

    Перед разбором примера следует заметить, что на рассматриваемом сайте информацию о вакансияхможно извлекать минимум тремя способами

    1. используя API сайта

    2. используя rss сайта

    3. непосредственно со страниц сайта

    Однако, не все сайты предоставляют такое разноообразие способов для извлечения данных. Поэтому, вданном примере мы рассмотрим наиболее универсальный (хотя, зачастую, и не самый удобный) способпод номером 3 - извлечение данных непосредственно со страниц сайта

    Следует понимать, что процесс извлечения данных может быть реализован несколькими путями. Что-бы выбрать наиболее эффективный путь (с точки зрения времени и трудозатрат) первым и самымважным этапом является анализ структуры сайта и страниц, хранящих необходимую информацию.

    7.1 Этап 1. Анализ сайта

    Анализ - творческий процесс, во многом зависит структурой сайта и определяет последующий способего парсинга.

    7.1.1 Сбор информации о ссылка сайта, хранящих необходимые данные

    Сбор информации может выполняться одним из двух способов

    17

  • mydoc Documentation, Выпуск 1

    Автоматический способ - самый простой но более длительный и подходит не для всех типов сайтов.Суть его заключается в том, чтобы дать парсеру указание обойти все доступные страницы сайта,извлечь из них все внутренние ссылки сайта и сохранить их в отдельный файл. Делается это следующейкомандой Затем нужно просмотреть файл со собранными ссылками и выделить те из них, по которымхранятся необходимые данные. Например Из листинга видно, что достаточно много ссылок имеюттакую структуру ___

    Перейдя по любой из них в браузере мы попадаем на страницу, содержащую нужные нам данные.Значит, именно эти страницы и нужно указать функции парсера для извлечения данных. Делаетсяэто примерно так

    Способ второй - ручной. Переходя в браузере по ссылкам сайта вручную определить ссылки какоготипа нам необходимы. Например ___

    Очевидно, что для данного способа нам нет нужны собирать все ссылки с сайта - мы можем выполнятьпарсинг генерируя их “на лету”. Генерировать ссылки можно, например таким кодом

    for j in ['http://hh.%(domen)s /data/%(id)s ?filter1=%(f)s &filter2=%(ff)s ' % {'id':str(i), 'domen':d, 'f':f, 'ff':ff}for d in ['com', 'ru']

    for i in xrange(1,10,1)for f in ['profession','employers']

    for ff in xrange(5)]:print j

    Первая особенность интернет сайтов как источника xml данных заключается в том, что данные хра-нятся по адресам (страниц) небольшими порциями. И таких адресов у сайта очень много. А крометого, сайт включает адреса к другим данным, нас не интересующим. В нашем примере это адреса наописание компаний, разместивших вакансии, адреса на страницы ___ и т.д. Нас интересуют толькоадреса с описанием вакансий.

    Поэтому, задача данного этапа - собрать все адреса сайта и оставить только те, по которым хранятсяинтересующие нас данные и.

    Решается эта задача с помощью следующего кода

    url='http://www.hh.ru'x=xmlParser(url, 'html')x.header={}x.html.getAllLinks(link_file='hh.lst', maxdeep=-1)

    Код сканирует сайт и сохраняет все адреса в файл hh.lst

    maxdeep важный параметр метода - определяет глубину поиска ссылок. Т.е. сначала изпервой (основной) страницы сайта извлекаются все ссылки на другие страницы. За-тем метод переходит по каждой этой ссылке и уже из этой страницы извлекает всессылкию Затем переходит по ним и опять извлекает все ссылки. Т.е. проходит вглубьсайта до уровня maxdeep. Значение -1 означает что ссылки будут извлекаться со всехдоступных страниц сайта.

    Задача данного метода - собрать достаточное количество ссылок, чтобы понять структуру сайта. По-этому иногда не обязательно собирать все ссылки, а ограничиться глубиной 5-10

    7.2 Этап 2. Анализ ссылок

    Теперь необходимо вручную провести небольшой анализ ссылок. Дело в том, что нужные нам одни ите же данные могут быть представлены на сайте в разных формах и по разным ссылкам (путям). Для

    18 Глава 7. Парсинг удаленного источника (сайта)

  • mydoc Documentation, Выпуск 1

    нашего примера это выглядит так. Мы собираем данные о вакансиях, размещенных на сайте. Вакансиипредставлены в следующих форматах

    1. Самая подробная информация информация о вакансии хранится на страницах сайта примернотакого формата https://hh.ru/vacancy/16718241. По таким ссылкам на каждой странице хранятсяданные только по одной вакансии

    2. Список вакансий хранится по ссылкам такого типа https://hh.ru/search/vacancy?page=3. Здесьна каждой странице хранится сокращенная информация по 20 вакансиям. Но есть ограниче-ние - максимально допустимое значение параметра -99. Т.о. меняя только этот параметр можнополучить данные о 2000 вакансиях. Чтобы получить больше данных - на помощь приходят от-фильтрованные списки.

    3. Отфильтронаннык списки вакансий хранятся по тому же адресу что и в 2https://hh.ru/search/vacancy?page=3, но с добавлением к адресу дополнительных фильтров,например https://hh.ru/search/vacancy?page=3&area=1 - вакансии по г. Москва. Просматриваяссылки - легко выделить следуюште параметры фильтров

    areaId - номер региона в котором размещена вакансия (__ уникальных значений)

    only_with_salary=true - вакансии только с указанной зарплатой

    salary - нижняя граница заработной платы

    experience=between1And3 - опыт работы

    specialization=21 - профессиональная область и специализации

    industry=5 - отрасль кампании

    label=not_from_agency - исключить вакансии агенств

    employment - тип занятости

    schedule - график работы

    Каждый параметр имеет ограниченное количество допустимых значений. Узнать их можно из спискассылок. для этого вызовем метод

    4. Список вакансий по профессиям хранятся по адресу https://hh.ru/catalog/Avtomobilnyj-biznes/Nachalnii-uroven/page-2

    5. Список краткого описания вакансий по кампаниям хранится по адресуhttps://hh.ru/employer/5406

    Такое разнообразие представления информации ___

    • Если мы хотим собрать наиболее полную базу вакансий для ___

    • если мы хотим проанализировать рынок вакансий в сравнении с общероссийской базой - лучшевсего использовать 3-й тип ссылок

    • если мы хотим регулярно отслеживать поступления новых вакансий по перечню определенныхпрофессий или по определенным кампаниям, например, чтобы при появлении таких вакансийавтоматически отправлять отчет на электронную почту, соотвественно используем 4 или 5 типссылок

    Далее в данном примере мы будем рассматривать задачу сравнения вакансий hh с общероссийскойбазой

    7.2. Этап 2. Анализ ссылок 19

    https://hh.ru/vacancy/16718241https://hh.ru/search/vacancy?page=3https://hh.ru/search/vacancy?page=3https://hh.ru/search/vacancy?page=3&area=1https://hh.ru/catalog/Avtomobilnyj-biznes/Nachalnii-uroven/page-2https://hh.ru/catalog/Avtomobilnyj-biznes/Nachalnii-uroven/page-2https://hh.ru/employer/5406

  • mydoc Documentation, Выпуск 1

    7.3 Этап 3. Извлечение данных по нужным ссылкам

    На данном этапе существует два подхода к извлечению данных. Точнее - к получению ссылок настраницы из которых парсер будет извлекать данные

    1. Указать шаблон для ссылок по которым хранятся необходимые нам данные

    2. Генерировать необходимые ссылки.

    Рассмотрим подробно оба этих способа. Ни один из них не является преимущественным, примене-ние того или иного способа зависит организации сайта, от времени, которым Вы располагается дляизвлечения данных и навыков программирования.

    7.3.1 Способ 1. Определение шаблона ссылок

    не работает

    7.3.2 Способ 2. Генерация ссылок

    Данный способ позволяет вообще пропустить этап 2 (сбор ссылок сайта) но при этом основан на пред-варительном ручном изучении существующих фильтров и их допустимых значений (см пункт 3 этапа2). После этого в коре парсинга необходимо сформировать словарь фильтров и их допустимых значе-ний, после чего можно запустить парсер для извлечения данных по генерируемым ссылкам. код будетпримерно такой ___ проверить оба способа и сравнить их точность ___

    20 Глава 7. Парсинг удаленного источника (сайта)

  • Глава 8

    Источники открытых данных xml

    Данный пополняемый список содержит открытые источники данных xml, содержащие различныеполезные и интересные наборы данных.

    8.1 Архивные данные для скачивания

    • Открытые данные ведомств России http://data.gov.ru/opendata. Содержит более 2500 наборов данных в формате xml. Наиболее интересными, на наш взгляд являются:

    – общероссийская база вакансий http://data.gov.ru/opendata/7710538364-vacansii

    • база данных ФИАС http://fias.nalog.ru/Updates.aspx

    • архив данных официального сайте Госзакупок __

    • открытый корпус русского языка http://opencorpora.org/?page=downloads

    8.2 Online данные

    • сайты объявлений:

    – Любые объявления

    ∗ http://irr.ru,

    ∗ https://www.avito.ru

    – Автомобили

    ∗ http://auto.drom.ru

    – Недвижимость:

    ∗ http://www.domofond.ru

    ∗ http://www.cian.ru

    – Работа:

    ∗ http://www.rabota.ru

    ∗ http://www.superjob.ru

    ∗ https://hh.ru

    21

    http://data.gov.ru/opendatahttp://data.gov.ru/opendata/7710538364-vacansiihttp://fias.nalog.ru/Updates.aspxhttp://opencorpora.org/?page=downloadshttp://irr.ruhttps://www.avito.ruhttp://auto.drom.ruhttp://www.domofond.ruhttp://www.cian.ruhttp://www.rabota.ruhttp://www.superjob.ruhttps://hh.ru

  • mydoc Documentation, Выпуск 1

    • Новостные ленты:

    – https://lenta.ru/rss

    – http://www.interfax.ru/rss.asp

    – http://inosmi.ru/export/rss2/index.xml

    – рубрики РИА http://ria.ru/docs/about/rss.html

    – РБК http://rss.rbc.ru

    • Разное

    – поиск людей в социальных сетях https://yandex.ru/people

    – рынки и биржевые котировки http://finance.rambler.ru

    8.3 API сервисы

    • геокодирование, http://nominatim.openstreetmap.org/search?q=%D0%A2%D1%8E%D0%BC%D0%B5%D0%BD%D1%8C&format=xml

    22 Глава 8. Источники открытых данных xml

    https://lenta.ru/rsshttp://www.interfax.ru/rss.asphttp://inosmi.ru/export/rss2/index.xmlhttp://ria.ru/docs/about/rss.htmlhttp://rss.rbc.ruhttps://yandex.ru/peoplehttp://finance.rambler.ruhttp://nominatim.openstreetmap.org/search?q=%D0%A2%D1%8E%D0%BC%D0%B5%D0%BD%D1%8C&format=xml

  • Глава 9

    Примеры применения парсера

    В данном разделе будут описываться практически реализованные примеры применения парсера.

    9.1 Получение списка городов и населенных пунктов РФ

    Исходный xml-файл можно скачать отсюда http://gis-lab.info/qa/vmap0-settl-rus.html

    Задача сконвертировать данные в формат JSON.

    Особенностью структуры xml-файла является то, что все данные хранятся в атрибутах.

    Итоговый код с применением xmlParser выглядит так

    x=xmlParser('np.xml', 'xml')data=x.getData(['osm/node', 'osm/node/tag'], get_attrib=True)d={}f=open('a.txt','w')f.write('[\n')for i in data:

    if len(i[1])>2:if d:

    f.write(simplejson.dumps(d, ensure_ascii=False, indent=4 * ' ').encode('utf-8')+',\n')d=dict(i[1])

    if len(i[1])==2:k,v=i[1].values()k=k.replace(':','_')d[k]=v

    f.write('\n]')f.close()

    23

    http://gis-lab.info/qa/vmap0-settl-rus.html

    ВведениеЧто такое парсингЗачем нужен парсинг данных?Алгоритм парсинга источников xmlТребования к программе-парсеру

    xmlPyParser. Быстрый стартАнализ структуры источника xmlИзвлечение данныхРезюме

    Возможности парсера xmlPyParserБазовые методы классаРасширение класса

    Расширенные методы парсераПриемы парсингаЗадание пути к данным в xml-источнике регулярным выражениемГенератор адресов доступа к xml источнику данных

    Парсинг базы вакансийАлгоритм

    Парсинг удаленного источника (сайта)Этап 1. Анализ сайтаЭтап 2. Анализ ссылокЭтап 3. Извлечение данных по нужным ссылкам

    Источники открытых данных xmlАрхивные данные для скачиванияOnline данныеAPI сервисы

    Примеры применения парсераПолучение списка городов и населенных пунктов РФ