Парсить сайты в Excel достаточно просто если использовать облачную версию софта Google Таблицы (Sheets/Doc), которые без труда позволяют использовать мощности поисковика для отправки запросов на нужные сайты.
- Подготовка;
- IMPORTXML;
- IMPORTHTML;
- Обратная конвертация.
Видеоинструкция
Подготовка к парсингу сайтов в Excel (Google Таблице)
Для того, чтобы начать парсить сайты потребуется в первую очередь перейти в Google Sheets, что можно сделать открыв страницу:
https://www.google.com/intl/ru_ru/sheets/about/
Потребуется войти в Google Аккаунт, после чего нажать на «Создать» (+).
Теперь можно переходить к парсингу, который можно выполнить через 2 основные функции:
- IMPORTXML. Позволяет получить практически любые данные с сайта, включая цены, наименования, картинки и многое другое;
- IMPORTHTML. Позволяет получить данные из таблиц и списков.
Однако, все эти методы работают на основе ссылок на страницы, если таблицы с URL-адресами нет, то можно ускорить этот сбор через карту сайта (Sitemap). Для этого добавляем к домену сайта конструкцию «/robots.txt». Например, «seopulses.ru/robots.txt».
Здесь открываем URL с картой сайта:
Нас интересует список постов, поэтому открываем первую ссылку.
Получаем полный список из URL-адресов, который можно сохранить, кликнув правой кнопкой мыши и нажав на «Сохранить как» (в Google Chrome).
Теперь на компьютере сохранен файл XML, который можно открыть через текстовые редакторы, например, Sublime Text или NotePad++.
Чтобы обработать информацию корректно следует ознакомиться с инструкцией открытия XML-файлов в Excel (или создания), после чего данные будут поданы в формате таблицы.
Все готово, можно переходить к методам парсинга.
IPMORTXML для парсинга сайтов в Excel
Синтаксис IMPORTXML в Google Таблице
Для того, чтобы использовать данную функцию потребуется в таблице написать формулу:
=IMPORTXML(Ссылка;Запрос)
Где:
- Ссылка — URL-адрес страницы;
- Запрос – в формате XPath.
С примером можно ознакомиться в:
https://docs.google.com/spreadsheets/d/1xmzdcBPap6lA5Gtwm1hjQfDHf3kCQdbxY3HM11IqDqY/edit#gid=0
Примеры использования IMPORTXML в Google Doc
Парсинг названий
Для работы с парсингом через данную функцию потребуется знание XPATH и составление пути в этом формате. Сделать это можно открыв консоль разработчика. Для примера будет использоваться сайт крупного интернет-магазина и в первую очередь необходимо в Google Chrome открыть окно разработчика кликнув правой кнопкой мыли и в выпавшем меню выбрать «Посмотреть код» (сочетание клавиш CTRL+Shift+I).
После этого пытаемся получить название товара, которое содержится в H1, единственным на странице, поэтому запрос должен быть:
//h1
И как следствие формула:
=IMPORTXML(A2;»//h1″)
Важно! Запрос XPath пишется в кавычках «запрос».
Парсинг различных элементов
Если мы хотим получить баллы, то нам потребуется обратиться к элементу div с классом product-standart-bonus поэтому получаем:
//div[@class=’product-standart-bonus’]
В этом случае первый тег div обозначает то, откуда берутся данные, когда в скобках [] уточняется его уникальность.
Для уточнения потребуется указать тип в виде @class, который может быть и @id, а после пишется = и в одинарных кавычках ‘значение’ пишется запрос.
Однако, нужное нам значение находиться глубже в теге span, поэтому добавляем /span и вводим:
//div[@class=’product-standart-bonus’]/span
В документе:
Парсинг цен без знаний XPath
Если нет знаний XPath и необходимо быстро получить информацию, то требуется выбрав нужный элемент в консоли разработчика кликнуть правой клавишей мыши и в меню выбрать «Copy»-«XPath». Например, при поиске запроса цены получаем:
//*[@id=»showcase»]/div/div[3]/div[2]/div[2]/div[1]/div[2]/div/div[1]
Важно! Следует изменить » на одинарные кавычки ‘.
Далее используем ее вместе с IMPORTXML.
Все готово цены получены.
Простые формулы с IMPORTXML в Google Sheets
Чтобы получить title страницы необходимо использовать запрос:
=IMPORTXML(A3;»//title»)
Для вывода description стоит использовать:
=IMPORTXML(A3;»//description»)
Первый заголовок (или любой другой):
=IMPORTXML(A3;»//h1″)
IMPORTHTML для создания парсера веи-ресурсов в Эксель
Синтаксис IMPORTXML в Google Таблице
Для того, чтобы использовать данную функцию потребуется в таблице написать формулу:
=IMPORTXML(Ссылка;Запрос;Индекс)
Где:
- Ссылка — URL-адрес страницы;
- Запрос – может быть в формате «table» или «list», выгружающий таблицу и список, соответственно.
- Индекс – порядковый номер элемента.
С примерами можно ознакомиться в файле:
https://docs.google.com/spreadsheets/d/1GpcGZd7CW4ugGECFHVMqzTXrbxHhdmP-VvIYtavSp4s/edit#gid=0
Пример использования IMPORTHTML в Google Doc
Парсинг таблиц
В примерах будет использоваться данная статья, перейдя на которую можно открыть консоль разработчика (в Google Chrome это можно сделать кликнув правой клавишей мыши и выбрав пункт «Посмотреть код» или же нажав на сочетание клавиш «CTRL+Shift+I»).
Теперь просматриваем код таблицы, которая заключена в теге <table>.
Данный элемент можно будет выгрузить при помощи конструкции:
=IMPORTHTML(A2;»table»;1)
- Где A2 ячейка со ссылкой;
- table позволяет получить данные с таблицы;
- 1 – номер таблицы.
Важно! Сам запрос table или list записывается в кавычках «запрос».
Парсинг списков
Получить список, заключенный в тегах <ul>…</ul> при помощи конструкции.
=IMPORTHTML(A2;»list»;1)
В данном случае речь идет о меню, которое также представлено в виде списка.
Если использовать индекс третей таблицы, то будут получены данные с третей таблицы в меню:
Формула:
=IMPORTHTML(A2;»list»;2)
Все готово, данные получены.
Обратная конвертация
Чтобы превратить Google таблицу в MS Excel потребуется кликнуть на вкладку «Файл»-«Скачать»-«Microsoft Excel».
Все готово, пример можно скачать ниже.
Пример:
https://docs.google.com/spreadsheets/d/1xmzdcBPap6lA5Gtwm1hjQfDHf3kCQdbxY3HM11IqDqY/edit
Всем привет, видел ваш форум пару дней назад когда искал информацию по моему вопросу… мои поиски оказались без результата и надеюсь тут мне помогут информацией, в РУнете я не нашёл информации по своей проблеме… бесплатной, а на платную пока финансов не имею, стипендия нынче не радует.
Вообщем в гугл таблицах есть такая замечательная штука как importxml, которая работает очень просто, =importxml(ячейка с линком;»код с сайта»).
В моём случае парсер выглядел так =importxml(A2;»//meta[@name=’description’]//@content»), он тащил мне строку с информацией.
Строчка кода HTML <meta name=»description» content=»Новая версия (Android)» />
Текст был любой, но главное было вытащить то , что в скобочках. Это я уже потом посчёт фильтров доставал.
К сожалению гугл ограничивается 100-ней запросов и потом виснет. Поэтому решил перейти на excel.
На знакомой со школы 2007-й версии не нашёл аналогичных формул, в ходе поиска выяснил, что таких нет и если и реально реализовать аналог importxml на excel 2007, то через VBA. А в этом я полный 0, т.к не научили, а сам никогда не задумывался в сторону этого языка.
Вообщем т.к время поджимает, перешёл я на версию 2013 года и познакомился с FILTERXML, и я вообще не понимаю как он работает.
По информации с открытых источников, дело выглядит так =FILTERXML(WEBSERVICE(A2),»//meta[@name=’description’]//@content»).
Но excel ругается на выделенный красным момент =FILTERXML(WEBSERVICE(A2),»//meta[@name=’description’]//@content»).
Заменять , на ; пробовал, не помогает.
В чём проблема не понимаю, если кто знает объясните пожалуйста.
Вопрос:
Мне нравится использовать функцию Документов Google = importxml(), но хотелось бы знать, было ли что-то подобное в Excel 2010? Кажется, я не могу найти способ автоматически вытащить данные из связанного файла XML.
Например, мне бы хотелось создать столбец с заголовком “Имя элемента”, а затем следующий столбец добавить имя, введенное пользователем в предыдущем столбце, на этот URL
http://util.eveuniversity.org/xml/itemLookup.php?name=
а затем проанализируйте полученный XML файл, чтобы вернуть идентификатор типа. Это выполняется в документах google, используя
=importxml(concatenate("http://util.eveuniversity.org/xml/itemLookup.php?name=",A3);"//itemLookup/typeID")
A3 – это столбец с именем элемента, который в этом случае будет Tritanium, и импортирует форму данных из полученного XML файла
http://util.eveuniversity.org/xml/itemLookup.php?name=Tritanium
который возвращает значение 34.
У меня есть список из примерно 20 наименований элементов, которые google docs автоматически обновляет идентификатор элемента при каждом открытии файла. Есть ли способ для Excel 2010 реплицировать эту функцию?
Спасибо!
Воля
Лучший ответ:
Вам нужно будет написать свой собственный UDF.
Один из способов – использовать библиотеку MSXML2
, что-то вроде этого:
Function GetData(sName As String, sItem As String, Optional sURL = "") As Variant
Dim oHttp As New MSXML2.XMLHTTP60
Dim xmlResp As MSXML2.DOMDocument60
Dim result As Variant
On Error GoTo EH
If sURL = "" Then
sURL = "http://util.eveuniversity.org/xml/itemLookup.php?name="
End If
'open the request and send it
oHttp.Open "GET", sURL & sName, False
oHttp.Send
'get the response as xml
Set xmlResp = oHttp.responseXML
' get Item
GetData = xmlResp.getElementsByTagName(sItem).Item(0).Text
' Examine output of these in the Immediate window
Debug.Print sName
Debug.Print xmlResp.XML
CleanUp:
On Error Resume Next
Set xmlResp = Nothing
Set oHttp = Nothing
Exit Function
EH:
GetData = CVErr(xlErrValue)
GoTo CleanUp
End Function
Вызвать это так (где A5
содержит требуемый typeName
)
=GetData(A5, "typeID")
Ответ №1
Вопрос с 2013 года, некоторое время прошло…
В Excel 2013 существует функция WEBSERVICE для загрузки документов XML, которые будут делать именно то, что вы хотите.
Существует также FILTERXML для поиска загруженного XML-документа с использованием XPath.
Ответ №2
Function ImportXML(url As String, query As String)
Dim document As MSXML2.DOMDocument60
Dim http As New MSXML2.XMLHTTP60
http.Open "GET", url, False
http.send
Set document = http.responseXML
ImportXML = document.SelectSingleNode(query).nodeTypedValue
End Function
Ответ №3
Функция “Из Интернета” в меню “Данные” будет выводить онлайн-данные непосредственно в электронную таблицу. Импорт XML-данных также доступен в подменю “От других источников”, также отображаемом в меню данных.
Созданные соединения управляются через диалоговое окно “Соединения” в меню “Данные”.
Пример кода с использованием макросов записи при создании соединения “From Web”:
Sub Macro1()
' Macro1 Macro
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://en.wikipedia.org/wiki/Microsoft_Excel" _
, Destination:=Range("$A$1"))
.Name = _
"?affID=110195&tt=270912_7a_3912_6&babsrc=HP_ss&mntrId=3e2fc48700000000000088532eb428ec"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End Sub
I love using Google Docs function =importxml() but would love to know if there was anything like it in Excel 2010? I cant seem to find a way for the program to automatically pull data from a linked XML file.
For example, I would love to be able to set up a column with the header «Item Name», then have the next column append the user-entered item name in the previous column to this url
http://util.eveuniversity.org/xml/itemLookup.php?name=
and then parse the resulting XML file to return the type ID. This is accomplished in google docs using
=importxml(concatenate("http://util.eveuniversity.org/xml/itemLookup.php?name=",A3);"//itemLookup/typeID")
A3 is the column that has the item name, which in this case would be Tritanium, and imports the data form the resulting XML file
http://util.eveuniversity.org/xml/itemLookup.php?name=Tritanium
which returns the value 34.
I have a list of about 20 item names that google docs automatically updates the item ID on every time I open the file. Is there any way for Excel 2010 to replicate this function?
Thanks!
Will
Я люблю использовать Google Docs function =importxml(), но хотел бы знать, было ли что-то подобное в Excel 2010? Я не могу найти способ для программы автоматически извлекать данные из связанного файла XML.
Например, я хотел бы иметь возможность установить столбец с заголовком «Имя элемента», а затем добавить в следующий столбец введенное пользователем имя элемента из предыдущего столбца к этому URL.
http://util.eveuniversity.org/xml/itemLookup.php?name=
а затем проанализируйте полученный XML-файл, чтобы получить идентификатор типа. Это выполняется в Google Документах с помощью
=importxml(concatenate("http://util.eveuniversity.org/xml/itemLookup.php?name=",A3);"//itemLookup/typeID")
A3 — это столбец с именем элемента, который в данном случае будет Tritanium, и импортирует данные из полученного XML-файла.
http://util.eveuniversity.org/xml/itemLookup.php?name=Tritanium
который возвращает значение 34.
У меня есть список из примерно 20 названий элементов, которые Google docs автоматически обновляет при каждом открытии файла. Есть ли способ для Excel 2010 для репликации этой функции?
Спасибо!
Будет
2013-01-04 21:28
4
ответа
Решение
Вам нужно будет написать свой собственный UDF.
Одним из способов было бы использовать MSXML2
библиотека, что-то вроде этого:
Function GetData(sName As String, sItem As String, Optional sURL = "") As Variant
Dim oHttp As New MSXML2.XMLHTTP60
Dim xmlResp As MSXML2.DOMDocument60
Dim result As Variant
On Error GoTo EH
If sURL = "" Then
sURL = "http://util.eveuniversity.org/xml/itemLookup.php?name="
End If
'open the request and send it
oHttp.Open "GET", sURL & sName, False
oHttp.Send
'get the response as xml
Set xmlResp = oHttp.responseXML
' get Item
GetData = xmlResp.getElementsByTagName(sItem).Item(0).Text
' Examine output of these in the Immediate window
Debug.Print sName
Debug.Print xmlResp.XML
CleanUp:
On Error Resume Next
Set xmlResp = Nothing
Set oHttp = Nothing
Exit Function
EH:
GetData = CVErr(xlErrValue)
GoTo CleanUp
End Function
Назовите это так (где A5
содержит необходимые typeName
)
=GetData(A5, "typeID")
2013-01-05 00:20
Вопрос с 2013 года, прошло некоторое время…
В Excel 2013 есть функция WEBSERVICE для загрузки документов XML, которая будет делать именно то, что вы хотите.
Существует также FILTERXML для поиска загруженного XML-документа с использованием XPath.
2015-04-24 19:33
Function ImportXML(url As String, query As String)
Dim document As MSXML2.DOMDocument60
Dim http As New MSXML2.XMLHTTP60
http.Open "GET", url, False
http.send
Set document = http.responseXML
ImportXML = document.SelectSingleNode(query).nodeTypedValue
End Function
2014-02-06 08:47
Функция «Из Интернета» в меню «Данные» перетаскивает онлайн-данные прямо в электронную таблицу. Импорт данных XML также доступен в подменю «Из других источников», которое также указано в меню данных.
Созданные соединения управляются через диалоговое окно «Соединения» в меню «Данные».
Пример кода с использованием макросов записей при создании соединения «Из Интернета»:
Sub Macro1()
' Macro1 Macro
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;http://en.wikipedia.org/wiki/Microsoft_Excel" _
, Destination:=Range("$A$1"))
.Name = _
"?affID=110195&tt=270912_7a_3912_6&babsrc=HP_ss&mntrId=3e2fc48700000000000088532eb428ec"
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingNone
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
End Sub
2013-01-06 01:33
Недавно меня попросили помочь с получением данных из интернета по стоимости ЕТФ фондов.
Первое, что пришло в голову — конечно же googlefinance()
Однако ТКСных ЕТФок там не оказалось. Данную проблему можно решить двумя способами — через регулярные выражения (и о них я поговорю в следующей статье) и стандартным способом — через встроенную гугл функцию importxml(). Взвесив все за и против, я решил пойти путём наименьшего сопротивления.
Почему так? Очень просто — кастом-функция по regExp через фетч, воспринимается как скрипт и, как следствие, подлежит квотированию со стороны гугла. Вообще тема квотирования, как и кэширования, для меня (и гугла) — больная и о ней я тоже как-нибудь напишу отдельно большой «возмущения пост» 🙂
Importxml принимает в себя два текстовых аргумента:
IMPORTXML(ссылка; запрос_xpath)
- ссылка – адрес веб-страницы с указанием протокола (например, http://).
- запрос_xpath – запрос XPath для поиска данных.
И если с ссылкой все понятно, то с запросом XPath может возникнуть сложность.
Вообще, если глубоко погружаться в XPath, то рекомендую почитать здесь: https://msiter.ru/tutorials/xpath.
Однако, есть более простой способ решить проблему понимания дерева xpath для тех, кому надо всё, сразу, здесь и сейчас.
XPath в хроме
Вернёмся к задаче, потому что на практическом примере это понять намного проще
У меня был список требуемых ЕТФ:
И, как писал ранее, таких тикеров в googlefinance нет.
Хорошо, перехожу на сайт — https://www.tinkoff.ru/invest/etfs/TSPX/ — и вижу стоимость:
Мне нужно получить в гугл таблицу 0,1199$
Для этого подвожу мышь к цене 0,1199 и перехожу в «Просмотреть код«
Стоимость находится тут:
Уже здесь можно скопировать путь Xpath:
и дальше просто вставить его в пустую ячейку таблицы.
Итого: у меня есть url и есть Xpath
Самое время посмотреть что получу через importxml:
Цена есть, правда знак доллара уехал.
Те, кто был чуть повнимательнее, заметили выше   — неразрывный пробел ( в данном случае их два) который как раз и разносит содержимое.
Что делать?
Подняться на уровень (а в случае сайта тинькофф — на два уровня) выше и импортировать все содержимое span класса со всеми переносами, пробелами, спец символами и так далее и тому подобное:
Получив в результате:
Победа? Ну… почти.
Все дело в том, что результат импорта «0,1199 $» — это текст и для дальнейших вычислений он не пригоден.
Из текста в цифру
Через стандартные функции:
- Удаляю пробелы (если они там есть) — Trim: =TRIM(A4)
2. Заменяю спецсимволы на пустоту — Subsitute: =SUBSTITUTE(B4;» «;»»)
3. Заменяю знак доллара на пустоту — Subsitute: =SUBSTITUTE(C4;»$»;»»)
4. Привожу результат к числовому значению — Value: =VALUE(D4)
Так как тикеры из списка не только долларовые, но и рублёвые, необходимо так же через substitute сделать замену «₽» на пустоту. Если в итоге объединить всё в одну формулу в рамках одной ячейки, получится примерно следующий «вложенный монстр»:
=VALUE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(TRIM(K2);» «;»»);»$»;»»);»₽»;»»))
Далее, дело за малым — распространить importxml и формулу выше на все тикеры.
Что же, первую часть задачи я решил. У меня есть цена на каждый указанный тикер.
Но это только пол дела. Цену надо ещё и обновлять.
И вот тут в дело вступают google apps scripts.
Переключатель ссылки (или просто Switcher)
Все дело в том, что гугл кэширует результаты выполнения importxml и обновляет их по одним гуглу известным алгоритмам. Я перерыл тонны вариантов решения этой проблемы где только можно и нельзя и самым «изящным» и приемлемым стал следующий: при обновлении ссылки (как аргумента importxml) гугл воспринимает ее как новую и заново перевыполняет функцию importxml.
То есть мне надо обновлять первый аргумент функции, при неизменном втором — xpath. Вот тут в действие и вступает так называемый «свитчер».
Это «условный» переключатель, который будет меняться с 1 на 0 скриптом.
Что все это значит? Написанный далее скрипт будет менять значение ячейки B1 c единицы на ноль (и обратно) и далее в зависимости от значения ячейки «свитчера» (1 или 0), будет меняться ссылка в importxml.
Чтобы она менялась на новую, но вела на тот же сайт за теми же значениями, я добавляю несуществующий параметр сайта ?Param=1
Скрипт
Перехожу в Apps script
и пишу следующий скрипт:
const ss = SpreadsheetApp.getActiveSpreadsheet()
// обращаюсь к книге
// далее обращаюсь к листу с параметрами, где хранится значение переключателя
const paramsWs = ss.getSheetByName("Params")
// имя ячейки где хранится 1 или 0
const SWITCHER_CELL = "B1"
// получаю диапазон (в данном случае ячейку)
const switcherCell = paramsWs.getRange(SWITCHER_CELL)
// получаю значение ячейки с 1 или 0
const switcherValue = switcherCell.getValue()
// если значение равно 1
if(switcherValue == 1){
// устанавливаю значение, равное 0
switcherCell.setValue(0)
// иначе
} else {
// устанавливаю значение, равное 1
switcherCell.setValue(1)
}
}
Ну и под конец….
Триггер — запуск по таймеру
Перехожу в «Триггеры«
В правом нижнем углу нажимаю
Выбираю свитчер (он у меня один)
Выбираю «триггер по времени»
Тип триггера — по минутам и далее — интервал
Сохраняю 🙂
Теперь гугл по триггеру будет сам включать свитчер. Свитчер будет менять свое значение (0 или 1) и, как следствие, вызывать пересчет importxml.
Небольшой комментарий. Как показала практика, при списках — т.е. где надо импортировать не одну запись, а целую таблицу записей, промежуток времени лучше ставить либо 15, либо 30 минут.
xPath это такой язык запросов, который позволяет среди множества элементов веб-страницы найти нужный, — и обратиться к нему, чтобы достать необходимые данные:
- Заголовок и описание.
- Названия статей с количеством просмотров.
- Список ссылок.
- Цены на товары.
- Изображения и т. п.
xPath поддерживают платные инструменты для парсинга (например, Screaming Frog Seo Spider), его выражения можно использовать в программировании на JavaScript, PHP и Python, и даже сделать простой бесплатный парсер прямо в Google Таблицах. Разбираемся, как именно — на трех практических примерах.
Когда начинаешь изучать большинство видео/статей по теме, начинает взрываться мозг — кажется, что все это очень сложно и подвластно только крутым технарям/хакерам. На самом деле все 200 встроенных функций xPath (как сообщает туториал W3C) знать совсем не обязательно, и на практике освоить язык получается гораздо проще. Процесс напоминает привычное ориентирование в папках и файлах в компьютере, а сами выражения xPath — адреса вроде «C:Program Files (x86)R-Studio».
1. Сбор и проверка заголовков и метатегов
Работа с заголовками (h1) и метатегами (title и description, реже keywords) — одна из составляющих поисковой оптимизации сайта. SEO-специалист (маркетолог, предприниматель) может проверять эти текстовые фрагменты на наличие, по длине, вхождениям определенных запросов. Если нужна массовая проверка, лучше воспользоваться специальным парсером (например, от Promopult или Click.ru), но небольшую задачу можно легко решить прямо в Google Spreadsheets.
Подготовка таблицы и разбор синтаксиса IMPORTXML
Начать можно с дизайна самой таблицы. Допустим, в первой колонке (A) будут ссылки на страницы, а правее уже результаты, извлеченные данные: H1, тайтл, дескрипшн, ключевые слова.
Тогда стоит первую строку отдать под заголовки (если планируются десятки ссылок, не помешает «Вид → Закрепить → 1 строку»), в A2 указать URL (можно пока любой — для проверки работоспособности) и приступить к написанию первой функции. (А так как текстовые фрагменты довольно длинные, можно заодно выделить все ячейки, нажать «Формат → Перенос текста → Переносить по словам».)
Начало работы с парсер-таблицей. В качестве примера разберем заголовки и метатеги главной страницы Webartex — это такая платформа для работы с блогерами и сайтами.
Для импорта данных с сайтов (в форматах HTML, XML, CSV) в Google Таблицах есть функция IMPORTXML. Она принимает такие аргументы:
- Полный адрес веб-страницы с указанием протокола (например, «https://»). Можно передать сам URL в кавычках или адрес ячейки, где он лежит.
- Непосредственно запрос xPath — тоже в кавычках, так как это тоже текстовая строка.
- locale — локальный код для указания языка и региона, необязательный параметр, по умолчанию используются настройки самого документа.
Читайте также: 20+ продвинутых функций Google Таблиц (Spreadsheets)
Составление функций для импорта XML с разными запросами xPath
Для парсинга H1 получится довольно просто: =IMPORTXML(A2;»//h1″).
«//» это оператор для выбора так называемого корневого узла — откуда нужно будет сразу взять данные или же «плясать» дальше (к дочернему элементу, соседнему или др.). В данном случае не нужно прописывать длинный путь, указывать дополнительные параметры — тег <h1> такой один единственный (как правило, но может быть и несколько заголовков первого уровня, тогда запрос «//h1» выгрузит их в несколько строк).
Вот что вернула функция IMPORTXML с «https://webartex.ru» по запросу «//h1»
Правда, есть нюанс — часть заголовка первого уровня оказывается в ячейке D2, а там нужны совсем другие данные. Все из-за тега <br>, который внутри <h1> используется для перевода строки. Решение — функция самого xPath «normalize-space()«, в которую нужно упаковать текст из H1. Дополненная функция получается такой: =IMPORTXML(A2;»normalize-space(//h1)»)
xPath-локатор работает корректно, можно идти дальше
В ячейке C2 — по тому же принципу, только выражение xPath, соответственно, будет «//title».
А вот для загрузки дескрипшна в соседнюю ячейку D2 нельзя указать просто «//description», потому что такого отдельного тега нет. Эти данные лежат в теге <meta>, у которого есть дополнительный параметр (атрибут) — «name» со значением «description«.
Если в запросе xPath нужно указать не просто элементы веб-страницы, а элементы с конкретным атрибутом, то соответствующие условия указываются в квадратных скобках. Название атрибута пишется с собакой «@», а его значение передается через одинарные кавычки. Если нужно проверить эквивалентность, то условие записывается просто как «атрибут = значение».
То есть для решения этой задачи нужно указать элемент так: «//meta[@name=’description’]».
Шпаргалка: из чего состоят HTML-элементы, из которых уже состоят веб-страницы (иллюстрация из курса Hexlet по основам HTML, CSS и веб-дизайна).
Однако если оставить такое выражение, то функция IMPORTXML вернет значение #N/A — значит, нет данных для импорта. Хотя путь к элементу указан верно. Дело в том, что внутри этого тега <meta> нет ничего — результат соответствующий.
Это хорошо видно, если открыть исходный код страницы (например, через сочетание клавиш Ctrl + U в Google Chrome). У <meta> нет закрывающего тега </meta>, как это бывает у многих других, получается, нет и внутреннего содержания. Нужные данные лежат в другом атрибуте — @content.
Исходный код страницы Webartex, на которых хорошо видно устройство тегов <meta>
Решение — дополнить запрос xPath, через «/» указав путь к конкретному атрибуту выбранного элемента. В данном случае вся формула будет такой: =IMPORTXML(A2;»//meta[@name=’description’]/@content»)
Если нужно указать не корневой элемент (узел), а его параметр или вложенный тег, тогда уже используется одинарный слеш, а не двойной. По аналогии с URL страниц сайтов или адресами файлов и папок операционной системы.
По такому же принципу составляется запрос для метатега с ключевыми словами — «//meta[@name=’keywords’]/@content». Если все ок, то, значит, можно протягивать формулы ниже, а в столбец URL добавлять новые адреса.
Результаты после запуска всех функций. Все формулы написаны верно, данные собираются корректно, все работает нормально.
Если нужно, аналогичным образом можно извлекать и другие данные: подзаголовки H2—H6, метатеги для разметки OpenGraph и Viewport, robots и др.
Читайте также: Микроразметка на сайте: что это, для чего нужно и как внедрить
Бонус: оценка полученных метатегов и заголовков
Допустим, нужно проверить, находится ли длина title и description в пределах нормы. Для этого можно воспользоваться функцией гугл-таблиц ДЛСТР (LEN). Она работает довольно просто: на входе текстовая строка, на выходе — число символов.
Согласно рекомендациям из блога Promopult, отображаемая длина тайтла в Google — до 50-55, а в Яндексе — до 45-55. Поэтому желательно не писать его слишком длинным, по крайней мере в первых 45–55 символах должна быть законченная мысль, самое главное о странице.
Чтобы не создавать дополнительных ячеек с цифрами по количеству символов, можно прописать формулу LEN в условном форматировании. Выделить третий столбец C, кликнуть в меню на «Формат → Условное форматирование», выбрать в списке «Правила форматирования» вариант «Ваша формула». И туда уже прописать, допустим, =LEN($C$2:$C)>55. А цвет, например, желтый, который как бы будет сигнализировать: «Тут надо посмотреть!».
В данном примере строка C2 пожелтеет, так как длина title составляет 59 знаков, а не 55. Но в принципе вся ключевая мысль, призыв к действию, умещается в лимит, так что все нормально.
Настройка условного форматирования Google Таблиц для подсвечивания тайтлов, длина которых больше рекомендуемой
По такому же алгоритму можно сделать оценку description. В вышеупомянутой статье blog.promopult.ru сказано: лучше, чтобы вся важная информация метаописания умещалась в 100-120 символов.
А еще там есть рекомендация не указывать в метатеге keywords больше 10 ключевых слов. Но чтобы проверить это, нужен не подсчет длины, а количества самих слов, разделенных запятыми.
В гугл-таблицах нет специальной функции, которая считает количество вхождений определенных символов в текстовую строку, но эту задачу можно решить через условное форматирование с помощью такой формулы: =COUNTA(SPLIT($E$2:$E;»,»))>10. Небольшой ликбез:
- SPLIT — разделяет текст по определенным символам и выводит в разные ячейки. Два обязательных параметра: 1) собственно, текст, который нужно разделить, или ссылку на ячейку с таковым 2) один или несколько символов в кавычках, по которым как раз и нужно разделять текст.
- СЧЁТЗ (COUNTA) подсчитывает количество значений в наборе данных: принимает неограниченное число аргументов (значений и диапазонов). В данном случае забирает на вход результаты SPLIT, выдающей массив текстовых значений, и подсчитывает их общее число.
А вот так работают эти функции отдельно (конечно, все результаты SPLIT не поместились, функция располагает их в строке, поэтому они уходят далеко вправо).
Получилось, что количество keywords на странице webartex.ru составляет 14, а не 10 штук, значит, их лучше подсократить. Яндекс может использовать этот метатег при ранжировании страницы, но большое количество ключевых слов может, наоборот, привести к пессимизации, исключению из индекса.
«Поисковое продвижение» — бесплатный видеокурс по SEO в обучающем центре CyberMarketing. В программе структура поисковой выдачи, санкции поисковых систем, инструменты для сбора семантического ядра и другие важные темы. Преподаватель — Евгений Костин, руководитель департамента продаж системы Promopult.
2. Парсинг ссылок из топ-10 поисковика
Допустим, нужно регулярно мониторить топ Яндекса по определенному запросу, чтобы узнать, попал ли туда конкретный сайт и на какую позицию. Можно с помощью xPath извлечь все ссылки с органической выдачи, а благодаря текстовым функциям Google Таблиц уже искать совпадения с названием нужного сайта.
Поиск и анализ нужных элементов через DevTools
В качестве примера — запрос «отложенный постинг». Для начала нужно в браузере Chrome перейти на соответствующую страницу, кликнуть правой кнопкой на один из элементов, который нужно будет извлечь (пусть это будет ссылка ниже заголовка), и нажать на «Просмотреть код» (горячие клавиши — Ctrl + Shift +I). Тогда откроются «Инструменты разработчика» (Chrome DevTools) с кодом этого элемента.
В коде документа сразу можно заметить древовидную структуру. На самом верху — корневой тег <html>, внутри на одном уровне <head> и <body>, затем <body> раскрывается на десятки <div> и <script>, а в некоторых <div> еще другие <div> с <ul>, <li>, <h2> и т. п. Написание xPath-запроса напоминает квест: нужно правильно описать искомый элемент и путь к нему.
Так выглядит просмотр кода нужного элемента в Chrome DevTools. (И было бы удобно кликнуть еще раз правой кнопкой, потом выбрать Copy и Copy XPath, затем вставить этот код в соответствующую функцию Таблиц, но, увы, как правило, так не работает. Приходится разбираться.)
Напоминаем: страница состоит из элементов, а каждый элемент включает тег и содержание (что между открывающим и закрывающим тегом), а еще в открывающем теге может быть дополнительная информация: атрибуты и их значения. В данном случае необходимые данные — ссылка на страницу, которая попала в топ Яндекса — находятся в значении атрибута «href» тега <a>, у которого еще есть атрибут «class» со значением «Link Link_theme_outer Path-Item link path__item i-bem link_js_inited«
(А этот тег <a> находится внутри тега <div> с атрибутом «class» и значением «Path Organic-Path path organic__path»… но весь путь писать нет смысла, если сам <a> достаточно уникальный и правильно находится.)
Фрагмент кода (на скриншоте он не помещается целиком):
<div class="Path Organic-Path path organic__path"><a class="Link Link_theme_outer Path-Item link path__item i-bem link_js_inited" tabindex="0" data-counter="["b"]" data-log-node="ip71w0i-02" href="https://blog.cybermarketing.ru/7-servisov-otlozhennogo-postinga-v-socialnye-seti-i-messendzhery/" target="_blank"><b>blog.cybermarketing.ru</b><span class="Path-Separator" aria-hidden="true" aria-label=" ">›</span>7-servisov…postinga-v…seti…</a></div>
Но прежде чем писать запрос xPath, стоит проверить — действительно ли все нужные элементы имеют соответствующие атрибуты и значения. «href», понятно, будет везде разный, а вот что насчет «class» со значением «Link Link_theme_outer Path-Item link path__item i-bem link_js_inited»?
Для этого в окне «Инструменты разработчика» нужно нажать «Ctrl + F» и внизу появится поле «Find by string, selector, or xPath». Если вставить эту большую и страшную строку, видно, что подсвечивается с десяток элементов.
В процессе поиска нужного значения в коде через Chrome DevTools. Вроде все хорошо, и подсвечиваются нужные элементы с необходимыми ссылками…
Ссылка из блока быстрых ответов не попадает — отлично, иначе она бы дублировалась. Но есть нюанс — и органическая, и платная выдача имеет такое же значение атрибута «class» тега <a>. Но их можно развести через дополнительное условие (все рекламные ссылки начинаются с «http://yabs.yandex.ru/»).
Читайте также: Чем отличается контекстная реклама от таргетированной
Написание xPath-локатора с учетом изученных элементов и их параметров
Вспоминаем: «//» — это оператор, который выбирает так называемый корневой узел — элемент для непосредственного извлечения данных или тот, от которого нужно будет дальше «плясать». Значит, нужно начать с «//a». Но если оставить так, то загрузятся все <a> со страницы, а для решения задачи нужны конкретные. То есть нужно указать, что нужен элемент <a> с атрибутом @class, у которого есть конкретное значение.
Делаем, как это уже было с метатегом дескрипшн из предыдущего раздела: атрибут с собакой, значение в одинарных кавычках, все условие в квадратных скобках → //a[@class=’Link Link_theme_outer Path-Item link path__item i-bem link_js_inited’] Можно проверить работоспособность запроса сразу же в «Инструментах разработчика» — в поле «Find by string, selector, or xPath». Вроде все работает.
Если перенести в Google Таблицы, формула получится такой: =IMPORTXML(«https://yandex.ru/search/?lr=45&text=отложенный постинг&p=0″;»//a[@class=’Link Link_theme_outer Path-Item link path__item i-bem link_js_inited’]») Но результат — #N/A!, нет данных для импорта.
Ах, да — как и в случае с description и keywords, искомые данные лежат в другом атрибуте. То есть нужно продолжить путь с помощью «/@href». Но функция снова не может импортировать данные.
Вроде все написано правильно, но импорт данных не работает…
На самом деле в атрибуте это не один такой класс с длинным названием, а несколько, которые разделены пробелами. Возможно, поэтому IMPORTXML не может найти данные по условию [@class=’]. Решение — искать не полное совпадение, а часть значения атрибута с помощью функции contains.
Если взять начало «Link Link_theme_outer Path-Item», то поиск по документу в DevTools выдает те же элементы, ничего лишнего не подмешивается. Значит, можно написать запрос таким образом: «//a[contains(@class,’Link Link_theme_outer Path-Item’)]»
Вставили в IMPORTXML такой запрос xPath — все заработало.
Функция contains через запятую принимает два аргумента: название параметра, где нужно искать вхождение, и текстовую строку, которую нужно искать. В данном случае нужно указать @class, но можно любой другой атрибут (или text(), если требуется найти вхождения во внутреннее содержание элемента). Альтернативой может стать другая функция starts-with — она ищет не в любом месте, а в начале строки. В данном случае результат такой же при «//a[starts-with(@class,’Link Link_theme_outer Path-Item’)]/@href».
Осталось только исключить из списка ссылки из контекстной рекламы, ведь нужна только органическая выдача. Для этого требуется указать два условия: чтобы взять все @href в теге <a> с классом, содержащим «Link Link_theme_outer Path-Item», но в то же время, чтобы в этих @href не было ссылок, где URL включает «yabs.yandex.ru». Решение — дополнить запрос xPath таким образом: «//a[contains(@class,’Link Link_theme_outer Path-Item’) and not(contains(@href,’yabs.yandex.ru’))]/@href»
Что здесь нового: логический оператор «and» указывает, что должны быть выполнены оба условия, а функция not() выполняет другую логическую операцию — отрицание. contains() внутри нее возвращает TRUE, когда находит в ссылке «yabs.yandex.ru», но в списке таковые как раз не нужны, поэтому TRUE надо превратить в FALSE. А логическое «И» работает только, когда оба условия — TRUE. Поэтому на выходе желаемый результат.
Выражение работает корректно: в списке URL’s органической выдачи, без рекламных ссылок и колдунщиков
Кстати, вместо <a> с классом, включающим «Link Link_theme_outer Path-Item», можно взять другую ссылку — с заголовков страниц. То есть составить запрос так: «//a[contains(@class, ‘OrganicTitle-Link’) and not (contains(@href, ‘yabs.yandex.ru’))]/@href» (ну и, конечно, вместо второй функции contains можно взять start-with, в данном случае все рекламные ссылки будут начинаться одинаково, с «http://yabs.yandex.ru»).
А если захочется парсить не первую страницу, а, допустим, вторую, то достаточно в URL — первом аргументе функции IMPORTXML — увеличить значение параметра &p (в конце ссылки) с нуля до единицы. То есть изменить адрес на «https://yandex.ru/search/?lr=45&text=отложенный постинг&p=1».
Читайте также: Исчерпывающий гид по поисковым операторам Google и Яндекса
3. Выгрузка статистики по популярным статьям в блоге
Допустим, автору (редактору, маркетологу или блогеру) хочется следить за популярными материалами в других медиа, чтобы черпать идеи по новым темам уже для своего ресурса. Можно делать это вручную — заходить на каждый сайт, скроллить, тратить время на поиск соответствующего блока — или собирать такие данные в таблицу. Рассмотрим, как это можно делать, на примере сайта Yagla (не самый посещаемый тематический ресурс, но интересный вариант с точки зрения освоения языка xPath).
Изучение сайта и подходящих элементов
На сайте yagla.ru много разных блоков, но для этих целей больше подходят два: «Обсуждаемое» (в самом верху) и «Самые читаемые статьи за последние 3 недели» чуть пониже. Информации по просмотрам нет, но есть количество комментариев (чтобы узнать просмотры, нужно открывать конкретную страницу, но, если нужно, можно с помощью дополнительных IMPORTXML загружать данные и по каждой из них).
Для начала: кликнуть правой кнопкой мыши на один из нужных заголовков в вышеперечисленных блоках, выбрать «Просмотреть код». Chrome DevTools подсвечивают тег <p> с атрибутом @class равным «small-post__title». Но если ввести это значение в поле «Find by string, selector, or xPath» видно, что оно есть и у материалов другого блока «Примеры роста конверсий, заказов и прибыли», который не нужно импортировать.
Начинаем изучать элементы главной страницы сайта в «Инструменты разработчика» Google Chrome
Родительский элемент, в который вложен вышеупомянутый <p>, — это <a> с классом ‘small-post‘. Но он еще более неуникальный, на странице таких 40 штук. Соседний (на одном и том же уровне) с <a> элемент — <h2> с классом «small-list__title title title_size_middle» тоже найден на странице в количестве четырех штук.
Но ведь можно прописать путь к элементу не только по значению атрибута, но и его содержанию, тексту.
Читайте также: Чек-лист: как проверить верстку
Составление запроса xPath
Обратиться к элементу можно и так — «//*[text()=’Обсуждаемое ‘]», чтобы взять только тот, где текст полностью соответствует строке ‘Обсуждаемое’. Сам тег в таком случае тоже прописывать необязательно.
Проверка первой части запроса xPath в DevTools показывает, что все ищется верно
Но при написании дальнейшего пути не получится как обычно продолжить с одинарным слешем, ведь нужен не потомок этого элемента, а элемент того же уровня — «сосед» («брат», «сестра»). В таких случаях нужен специальный оператор — ‘following-sibling::’. В итоге выражение xPath получится таким: «//*[text()=’Обсуждаемое ‘]/following-sibling::a/p». (Дополнительно указывать классы для <a> и <p> нет необходимости, так как других похожих вариантов путей нет.)
Таким же способом можно составить выражение для загрузки данных из другого блока: «//*[text()=’Самые читаемые статьи за последние 3 недели ‘]/following-sibling::a/p»
Базовая настройка и оформление таблицы
Как вариант. В ячейку A1 положить заголовок «Обсуждаемое», а ниже — в A2 — уже написать функцию: =IMPORTXML(«https://yagla.ru/»;»//*[text()=’Обсуждаемое ‘]/following-sibling::a/p»). Затем оставить необходимое пространство (если ячейки будут заняты, функция не сможет отобразить результаты), A5 отдать под следующий заголовок, а в A6 — вторую формулу: =IMPORTXML(«https://yagla.ru/»;»//*[text()=’Самые читаемые статьи за последние 3 недели ‘]/following-sibling::a/p»)
Такая вот таблица с популярными материалами получается в итоге
Внутри искомого <p> есть еще <span> с указанием формата, поэтому IMPORTXML требуется дополнительный столбец справа. (Так как эта информация излишняя, можно просто выделить все ячейки B, кликнуть правой кнопкой и выбрать «Скрыть столбец».)
‘following-sibling::’ — это одна из осей, основы запросов языка xPath. Есть и другие, например, ‘child::’ — возвращает множество потомков на один уровень ниже; ‘attribute::’ — выдает, соответственно, атрибуты; ‘parent::’ — ищет родительский узел. И с частью этих осей мы уже знакомы, просто для наиболее распространенных действуют сокращения. Так, child:: вообще прописывать необязательно, а attrubute:: заменяется на ‘@’.
Бонус: прокачка мини-парсера в Google Spreadsheets
Допустим, названия статей мало, нужны еще и просмотры, которых нет на главной странице. Тогда придется немного усовершенствовать гугл-таблицу. Разберем на примере блока «Обсуждаемое» — с другим все будет так же.
Для начала нужно выгрузить URL’s материалов. Как обычно ссылки лежат в атрибутах @href тега <a>, так что достаточно просто поменять концовку выражения xPath: «//*[text()=’Обсуждаемое ‘]/following-sibling::a/@href».
Все работает — в таблице появились ссылки на статьи.
Правда, ссылки не полные, а относительные — нужно превратить их в URL’s с названием домена. Решить задачу можно с помощью текстовой функции гугл-таблиц — СЦЕПИТЬ (CONCATENATE). Она работает просто: принимает на вход несколько строк, а возвращает объединенный текст.
В отдельном столбце можно дополнить выгруженные относительные ссылки до полных путей
Дальше уже к каждой странице сделать отдельные запросы xPath, чтобы извлечь данные со счетчика просмотров. Если посмотреть через DevTools, таковые находятся в теге <div> c атрибутом @class равным ‘post__prop‘. Однако элемент есть и наверху, и внизу, а в таблице нужен один. В такой ситуации в квадратных скобках указывается индекс, порядковый номер (если говорить терминами xPath — предикат).
Судя по шпаргалкам и справочникам, кажется, что нужно просто написать «//div[@class=’post__prop’][1]», но в таблице все равно оказываются два значения — да еще и с лишними пустыми ячейками.
Пока что получился такой некрасивый результат
Однако эксперты Stackoverflow разъясняют, что такой синтаксис работает только для последовательности узлов, а если нужен корневой элемент, то понадобятся дополнительные скобки: «(//div[@class=’post__prop’])[1]».
А лишние ячейки появляются из-за того, что внутри этого div есть еще теги. Чтобы почистить данные, понадобится применить функцию text(). Итоговая формула в гугл-таблицах получается такой: =IMPORTXML(D2;»(//div[@class=’post__prop’])[1]/text()»)
Остается только протянуть ее ниже — для всех строк с выгруженными URL статей.
Доработанная таблица с выгрузкой просмотров
Читайте также: Где вести блог, если нет своего сайта: 10 платформ для личного и корпоративного блогинга
Подытожим
xPath в гугл-таблицах — мощная штука, однако подходит только для решения относительно простых задач.
Так, при наличии большого количества формул типа IMPORTHTML, IMPORTDATA, IMPORTFEED и IMPORTXML результаты могут грузиться очень долго — а польза парсинга как раз в том, что можно быстро добывать свежие данные. К тому же, например, статистику Яндекс.Вордстат не получится извлечь через xPath — для работы нужна авторизация, да и даже при ручном сборе сервис может замучать капчей.
Поэтому для более серьезных задач по продвижению/оптимизации нужны профессиональные инструменты, например, Promopult. Там большой выбор решений для SEO- и PPC-специалистов: парсинг Wordstat и метатегов, сбор поисковых подсказок и кластеризация запросов, поиск и генерация объявлений и др. Один запрос стоит от 0.01 руб.