Почти год назад я опубликовал запись по тому, как можно было легко и в целом просто парсить данные с сайта https://www.tinkoff.ru/invest/ стандартными способами через importxml
С тех пор утекло много воды и парсить указанным выше способом стало невозможно. Ну а может и возможно, но у меня не вышло. Вообще я заметил такую тенденцию, что много кто меняет код, ставит блокировки и importxml
перестает работать. Защита данных и все такое…. Ну что ж! 🙂
Здравствуй tinkoff.ru/invest
Как обычно иду на сайт — https://www.tinkoff.ru/invest/etfs/TGLD/
Нужно что? Правильно, цена ETF — 0.0712

Далее в консоль. Сразу на 0.0712 она не открывается. Проваливаюсь в тег body и начинаю идти ниже, ища в отображении нужный класс (или еще раз щелкаю просмотр кода на цене):

проваливаюсь через F2 в:
<span class="SecurityInvitingScreen__priceValue_c1Ah9" data-qa-file="SecurityInvitingScreen"><span data-qa-type="uikit/money" class="Money-module__money_UZBbh">0<span data-qa-file="Money">,0712 $</span></span></span>
необходимый кусок — >0<span data-qa-file="Money">,0712 $<
Script Editor
Пишу код:
function getSpecificPrice() {
url = "https://www.tinkoff.ru/invest/etfs/TGLD/"
expr = /class="Money-module__money_UZBbh">(.*?)\$</g
const urlText = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
const testExpr = expr.test(urlText)
console.log(testExpr)
const array = [...urlText.matchAll(expr)];
console.log(array[0][1])
const value = array[0][1].replace('<span data-qa-file="Money">', "").split("<")
console.log(value[0])
return value[0]
url = "https://www.tinkoff.ru/invest/etfs/TGLD/"
— откуда фетчим данные
expr = /class="Money-module__money_UZBbh">(.*?)\$</g
— регулярное выражение для ETF, обязательно с ключом /g
потому что далее будет идти matchAll
Важно!!! Выражение /class="Money-module__money_UZBbh">(.*?)
работает для ETF. Для акций, облигаций надо собирать своё регулярное выражение.
const urlText = UrlFetchApp.fetch(url, { muteHttpExceptions: true }).getContentText();
— получаю все с сайта
const testExpr = expr.test(urlText)
и console.log(testExpr)
— проверяю вообще есть ли совпадения по регулярному выражению.

Получаю результат в виде true
— значит что-то есть.
const array = [...urlText.matchAll(expr)]
; и console.log(array[0][1])
— мэтчу всё, что есть по данной регулярке и методом проб и ошибок нахожу, что стоимость хранится в array[0][1]

далее, не претендуя на красоту и изящность кода (на 100% уверен, что можно и красивее, но мне не хочется), убираю span
, затем разделяю через <
элементы в массив
const value = array[0][1].replace('<span data-qa-file="Money">', "").split("<")
первый элемент массива будет ни что иное как цена.
console.log(value[0])

return value[0]
— возвращаю результат работы функции.
Табличная часть
Создаю лист с именем «Log», делаю шапку

Возвращаюсь в редактор скриптов, пишу простой код:
function logValue(){
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ws = ss.getSheetByName("Log");
const date = new Date()
ws.appendRow([date, getSpecificPrice()])
}
Пару раз запускаю функцию logValue()
, проверяю работу:

Вот и всё. Далее можно завесить logValue()
на триггер по времени и вести всю необходимую статистику.
Ваше мнение важно и может улучшить блог
Я хочу услышать ваше мнение и ваши идеи о том, как сделать этот сайт еще лучше. Примите участие в опросе, чтобы поделиться вашими пожеланиями, предложениями и замечаниями. Пройдите опрос сейчас и помогите сделать этот сайт более полезным для вас!
Спасибо за прошлый ответ, насчёт appenRow
А как мне извлечь так же, как в статье, цену с сайта https://www.coingecko.com/en/coins/terra-luna-classic ?
Вопрос в том, Регулярка — это RegEx или можно брать Xpath как при importXml?
Мне бы сам принцип понять, что вставлять в строку, где expr = **** (.*?)\$</g
И на что мы меняем в const value = array[0][1].replace('********', "").split("<")
И нужен ли switcher здесь, или интервал где-то заранее задан?
PS/ Попробовал всё с Тиньковым как здесь, но получилась только одна запись, вместо тайминга.
В коде не понимаю, мне для других задач нужно
Спасибо
SyntaxError: Identifier ‘ss’ has already been declared
(функция без названия) @ Switcher_Sheet — Log.gs:1
Вот такая ошибка
Ответ отправил в почту
Спасибо! Буду разбираться, и подбирать значения для аналогичного парсинга и на других сайтах!
Добрый день, а как здесь можно получить данные не из функции, а из конкретной ячейки или области?
function logValue(){
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ws = ss.getSheetByName(«Log»);
const date = new Date()
ws.appendRow([date, getSpecificPrice()])
}
Вместо «getSpecificPrice()» что должно быть?
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getRange(Integer,Integer)
Привет, можешь пожалуйста помочь?
В строке кода: expr = /class=»Money-module__money_UZBbh»>(.*?)\$(.*?) а эту часть оставлять не изменной?
Или так же нужно изменять?
Так же не до конца понял как ты пришел к тому в какой именно ячейки массива находится нужные нам данные?
Сайт с данными этот хотел использовать https://p2p.binance.com/en/trade/TinkoffNew/USDT?fiat=RUB
1. Менять надо конечно, судя по тегам, там другие классы:
div data-tutorial-id="trade_price_limit" class="css-1kj0ifu" div class="css-1m1f8hn"66.67
2. По поводу массива — matchAll загоняет все совпадения в массив. Потом просто смотрю на все элементы массива и забираю нужные.