Регулярные выражения если вы (как и я) — не программист.

Скажу честно:

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

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

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

  1. https://learn.javascript.ru/regular-expressions
  2. Не бойтесь регулярных выражений:

3. https://regex101.com/

А теперь практика

Пару месяцев назад меня попросили получить определённые данные с авито. И, к сожалению, importxml c этой задачей не справился.

Задача была следующей: нужно было получать данные с первой страницы по недвижимости в Тамбове — наименование, стоимость, ссылка на объект недвижимости.

Чтобы это сделать в гугл скриптах есть такой класс как UrlFetchApp.

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

Получаю необходимую страницу целиком

function getRegExpression() {
const link = 'https://www.avito.ru/tambov?f=ASgCAgECAUXGmgwXeyJmcm9tIjoxMDAwMDAwLCJ0byI6MH0&q=%D0%A2%D0%B0%D0%BC%D0%B1%D0%BE%D0%B2+%D0%BD%D0%B5%D0%B4%D0%B2%D0%B8%D0%B6%D0%B8%D0%BC%D0%BE%D1%81%D1%82%D1%8C'
const response = UrlFetchApp.fetch(link.toString(), {muteHttpExceptions: true });
const text = response.getContentText();
console.log(text)
}

У меня есть ссылка — коммерческая недвижимость Тамбова : const link =

const response = UrlFetchApp.fetch(link.toString(), {muteHttpExceptions: true });

фетчит эту станицу как объект

muteHttpExceptions согласно гугл мануалу не прекращает фетчить если код возвращает какую-либо ошибку: If true, the fetch doesn’t throw an exception if the response code indicates failure, and instead returns the HTTPResponse. The default is false.

const text = response.getContentText(); получает содержимое http ответа в виде строки…. в виде одной очень большой строки 🙂

Из которой как раз при помощи регулярных выражений и надо выдернуть необходимые данные!

Регулярные выражения

Если совсем просто то это шаблон на основе тегов из полученного текста. Но с нюансами в виде чисел, символов, спецсимволов — в общем всего, что объясняется выше по первым двум ссылкам.

1. Получаю название недвижимости

Уже по известному пути, иду в код страницы

Наименование хранится здесь:

Копирую его на сайт regex101 и начинаю «собирать»

Результат будет выглядеть следующим образом:

У меня, как и говорил ранее, нет цели объяснить как строится регулярное выражение, потому as is:

class=»title-root-j7cja iva-item-title-_qCwt title-listRedesign-XHq38 title-root_maxHeight-SXHes text-text-LurtD text-size-s-BxGpL text-bold-SinUO»>(.*?)<

беру полученный результат и переношу в скрипт

const myArr = […text.matchAll(expression)];
console.log(myArr)

Точнее, чем написано на developers mozilla сказать нельзя: метод matchAll() возвращает итератор по всем результатам при сопоставлении строки с регулярным выражением.

т.е. он вернул массив вообще со всем содержимым, где встречается требуемое регулярное выражение.

Само название — в данном случае «2-к. квартира, 53,9 м², 6/9 эт.» — это второй элемент в массиве.

через метод map получаю его:

const resultArray = myArr.map(cell => [cell[1]]);

И это уже привычный и «милый сердцу» массив массивов.

Теперь его осталось только вернуть на лист. И вот тут есть нюанс. Через setValue() или setValues() это сделать невозможно. Гугл не позволяет записывать (выводить) данные пользовательской функции более чем в одну ячейку.

Но решение есть. Массив можно просто вернуть:

return resultArray;

и тогда в текущей ячейке и ниже выведутся все результаты.

Итоговый скрипт пользовательской функции

function getDataFromURL(response, expr) {
const responsed = UrlFetchApp.fetch(response.toString(), {muteHttpExceptions: true });
const express = expr.toString();
const text = responsed.getContentText();

if(responsed && express){
const rate = [...text.matchAll(express)];
const resultArray = rate.map(cell => [cell[1]]);

const ss = SpreadsheetApp.getActiveSpreadsheet();
const ws = ss.getActiveSheet();
const activeCell = ws.getActiveCell().getA1Notation();
ws.getRange(activeCell).activate;

return resultArray;
} else {return "не указана ссылка или выражение"}
}

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

Добавить комментарий