Страницы: 1
RSS
Power Query извлечь данные СSS HTML
 
Создалась следующая для меня трудновыполнимая задача  :( . Буду благодарен за оказанную помощь.

Имеется страница в интернете https://meteoinfo.ru/forecasts/russia/vologda-area/vologda

необходимо из нее извлечь данные по облачности и осадкам (не картинки), которые находятся, как я понимаю, в таблице стилей СSS.
А также извлечь направление ветра - оно тоже в виде иконки.
Как это сделать, ума не приложу :cry:  
 
Power Query вам не поможет
СSS  не хранит данные, это каскадные страницы стилей вебстраниц, описывают внешний вид кнопок, форм и т.д.

для обработки данных с Веб вам пожет парсинг
вариант 1. изучить  MSXML2.XMLHTTP.6.0 в паре с HTMLDocument
вариант 2. изучить InternetExplorer.Application - легче в освоении
для первичного ознакомления
Это все требует знания VBA.
Изменено: TSN - 16.02.2021 16:57:44
 
А как же ?
https://docs.microsoft.com/ru-ru/powerquery-m/html-table
https://www.poweredsolutions.co/2018/05/14/new-web-scraping-experience-in-power-bi-power-query-using-css-selectors/
https://ssbipolar.com/2018/10/27/web-scraping-with-html-table-in-power-query/

что-то люди делают с CSS, только для меня это высшая математика.

TSN, спасибо ВАМ за ссылки на информацию.
Но все же может кто поможет решить задачу с помощью запроса Power Query?
 
Так надо?
Код
let
    Source = Web.Page(Web.Contents("https://meteoinfo.ru/forecasts/russia/vologda-area/vologda")){1}[Data],
    Headers = Table.PromoteHeaders(Source, [PromoteAllScalars=true])
in
    Headers
Изменено: PooHkrd - 16.02.2021 17:24:21
Вот горшок пустой, он предмет простой...
 
Цитата
Power Query вам не поможет
Возможно я поспешил с выводом по поводу Power Query. Но эту технологию точно придется изучать, если есть желание ее использовать/
Последняя версия Power BI Desktop вышла с новым веб-соединителем, специально разработанным для сценариев веб-парсинга.
 
TSN, на этом сайте нечего парсить. Функция Web.Page распознает табличные данные и можно их тепленькими. Вот если парсить то это примерно по такому сценарию. Там да - бывает не просто.
Вот горшок пустой, он предмет простой...
 
Разделители текста:
<img src=""/images/ico/ - https://meteoinfo.ru/images/ico/13d_s.png
Направление ветра - fa fa-arrow-up ihmc_wind
 
Цитата
PooHkrd написал:
Так надо?
Так - не надо. Так - это стандартный запрос. Это я и сам сделал. нужно именно решение по парсингу данных, что описаны в первом моем сообщении. По осадкам с облачностью и направлению ветра, а не его значению в м/с. В вашем решении (Стандартный запрос) этого нет!  :sceptic:

Цитата
Михаил Л написал:
Направление ветра - fa fa-arrow-up ihmc_wind
на картинке, что я приложил направление ветра задано в  span title , "Ю"  и в подсказке  <alt>  - "Ю"  
то есть южный. Необходимо "выдернуть" именно эти значения.
 
Цитата
Сергей Чернов написал:
В вашем решении (Стандартный запрос) этого нет!
Помимо стандартного решения я дал также ссылку на статью где расписывается частный случай парсинга HTML-кода. Также на форуме есть минимум три примера парсинга при помощи PQ, которые в общем и целом повторяют схему из статьи. Ознакомьтесь и применяйте, там в тексте кода видны все ваши облачности и направления. Как бы направление куда копать - имеется. Если нужно чтобы сделали за вас - велкам на ветку работа. Процесс сбора там трудоемкий и нудный, за интерес его делать желания нет от слова совсем.
Вот горшок пустой, он предмет простой...
 
Если очень надо, то можно преобразовать эти элементы в необходимый текст с помощью jQuery до передачи в Power Query. Единственное, могут потребоваться права администратора для внесения изменений в реестр.
 
Цитата
Андрей Лящук написал:
с помощью jQuery до передачи в Power Query.
Привет, тёзка.
А что мешает использовать jQuery в Power Query? Скрипты же можно заставить выполнить, можно.
 
Цитата
PooHkrd написал:
если парсить то это примерно  по такому сценарию .
можно и сразу в PQ парсить. Это я ТС-у :) Здесь пример приводил подобной проблемы: Производственный календарь в Excel (VBA и Power Qwery)
Да, придется повозиться. Вот, начало отбора:
Код
let
    Source = Table.FromColumns({Lines.FromBinary(Web.Contents("https://meteoinfo.ru/forecasts/russia/vologda-area/vologda&quot;))}),
    CsvURLText = Table.SelectRows(Source, each Text.Contains([Column1], "fc_small_gorizont_ww")),
    URLText = CsvURLText{0}[Column1],
    url_start_pos = Text.PositionOf(URLText,"fc_small_gorizont_ww"),
    url_end_pos = Text.Length(URLText),
    url = Text.Middle(URLText,url_start_pos,url_end_pos-url_start_pos+20),
    res = Text.Split(url,"fc_small_gorizont_ww")
in
    res
дальше пробуйте сами вытащить то, что надо именно Вам.
Изменено: Дмитрий(The_Prist) Щербаков - 17.02.2021 09:45:11
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
Андрей VG написал:
Привет, тёзка.А что мешает использовать jQuery в Power Query?
Добрый день, ну я это и имел ввиду, утром мозг еще спит, не совсем корректно мыслю выразил
 
Андрей Лящук, Здравствуйте!
Вы что, за границей были? Так долго не видать вас было :)  
 
Цитата
PooHkrd написал:
TSN , на этом сайте нечего парсить.
Парсинг – это автоматизированный процесс извлечения данных с веб-сайта. Так, что любой метод извлечения данных можно назвать парсингом.
Цитата
PooHkrd написал:
Вот если парсить то это примерно  по такому сценарию . Там да - бывает не просто.
Необязательно по такому.
Вот пример решения без использования jQuery, Power Query, по сценарию который я предложил изначально.
(извлечь данные по облачности и осадкам (не картинки), также извлечь направление ветра)
Если для ТС приемлемо такое решение пусть пользуется.
Код
Option Explicit
Option Compare Text
''' объект objHTMLDoc As HTMLDocument, объявлен ранним связыванием
''' Tools -> References -> Microsoft HTML Object Library. > C:\Windows\SysWOW64\mshtml.tlb
''' Для примера страница сайта с которой берем данные
Private Const strURL As String = " https://meteoinfo.ru/forecasts/russia/vologda-area/vologda"
 
Sub Parser_meteoinfo1 ()
Dim objHTMLDoc As HTMLDocument
Dim objXML As Object, Tag1, vl1, vl2
Dim strOtvetAukcion As String, strTrimer As String
Dim arr(), i As Long, x As Long

Set objHTMLDoc = New HTMLDocument
Set objXML = CreateObject("MSXML2.XMLHTTP.6.0")
objXML.Open "GET", strURL, False
objXML.setRequestHeader "Accept", "*/*"
objXML.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/58.0.1"
objXML.setRequestHeader "Proxy-Connection", "Keep-Alive"
objXML.setRequestHeader "Cache-Control", "no-cache"
objXML.setRequestHeader "If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 UTC"
objXML.setRequestHeader "Content-Type", "text/xml"
objXML.sEnd
While objXML.readyState <> 4: DoEvents: Wend
objHTMLDoc.body.innerHTML = objXML.responseText

''' набор данных
Set Tag1 = objHTMLDoc.getElementsByTagName("tr")
ReDim arr(1 To Tag1.Length, 1 To 2)
arr(1, 1) = "Осадки, день"
arr(1, 2) = "Ветер, м/с"

For Each vl1 In Tag1
  If vl1.innerHTML Like "*fc_small_gorizont_ww*" Then
    If vl1.innerHTML Like "*День*" Then
    ' извлечь данные по облачности и осадкам
      i = 1: x = 1
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "День" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title
        End If
      Next
    End If
    If vl1.innerHTML Like "*Ветер, м/с*" Then
    ' извлечь направление ветра, скорость
      i = 1: x = 2
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "Ветер, м/с" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title & ", " & vl2.innerText
        End If
      Next
    End If
  End If
  If x = 2 Then Exit For
Next
'' Поместить результат запроса на лист
ThisWorkbook.Sheets(1).Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)) = arr

Set objHTMLDoc = Nothing
Set objXML = Nothing
End Sub

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

Код
Option Explicit
Option Compare Text
''' объект objHTMLDoc As HTMLDocument, объявлен ранним связыванием
''' Tools -> References -> Microsoft HTML Object Library. > C:\Windows\SysWOW64\mshtml.tlb

Sub Parser_meteoinfo()
Dim objHTMLDoc As HTMLDocument
Dim objXML As Object, Tag1, vl1, vl2
Dim strOtvetAukcion As String, strTrimer As String
Dim arr(), i As Long, x As Long

''' страница сайта с которой берем данные
Dim strURL As String
strURL = "https://meteoinfo.ru/forecasts/russia/vologda-area/vologda"

Set objHTMLDoc = New HTMLDocument
Set objXML = CreateObject("MSXML2.XMLHTTP.6.0")
objXML.Open "GET", strURL, False
objXML.setRequestHeader "Accept", "*/*"
objXML.setRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/58.0.1"
objXML.setRequestHeader "Proxy-Connection", "Keep-Alive"
objXML.setRequestHeader "Cache-Control", "no-cache"
objXML.setRequestHeader "If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 UTC"
objXML.setRequestHeader "Content-Type", "text/xml"
objXML.sEnd
While objXML.readyState <> 4: DoEvents: Wend
objHTMLDoc.body.innerHTML = objXML.responseText

''' набор данных
Set Tag1 = objHTMLDoc.getElementsByTagName("tr")
ReDim arr(1 To Tag1.Length, 1 To 4)
arr(1, 1) = "Осадки, день"
arr(1, 2) = "Ветер, м/с"
arr(1, 3) = "Осадки, ночь"
arr(1, 4) = "Ветер, м/с"

For Each vl1 In Tag1
  If vl1.innerHTML Like "*fc_small_gorizont_ww*" Then
    Debug.Print vbNewLine
    Debug.Print vl1.innerHTML
    If vl1.innerHTML Like "*День*" Then
    ' извлечь данные по облачности и осадкам
      i = 1: x = 1
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "День" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title
        End If
      Next
    End If
    If vl1.innerHTML Like "*Ветер, м/с*" And _
    Not vl1.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
    ' извлечь направление ветра, скорость
      i = 1: x = 2
      For Each vl2 In vl1.Cells
        If vl2.innerText <> "Ветер, м/с" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title & ", " & vl2.innerText
        End If
      Next
    End If
    
    If vl1.innerHTML Like "*Ночь*" Then
    ' извлечь данные по облачности и осадкам за ночь
      i = 1: x = 3
      For Each vl2 In vl1.Cells
        If vl2.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title
        End If
      Next
    End If
    If vl1.innerHTML Like "*Ветер, м/с*" And _
       vl1.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
    ' извлечь направление ветра, скорость за ночь
      i = 1: x = 4
      For Each vl2 In vl1.Cells
        If vl2.innerHTML Like "*fc_small_gorizont_ww sdvig_div*" Then
          i = i + 1
          arr(i, x) = vl2.Children.Item(0).Children.Item(0).Title & ", " & vl2.innerText
        End If
      Next
    End If
  End If
  If x = 4 Then Exit For
Next
'' Поместить результат запроса на лист
ThisWorkbook.Sheets(1).Range("A1").Resize(UBound(arr, 1), UBound(arr, 2)) = arr

Set objHTMLDoc = Nothing
Set objXML = Nothing
End Sub





Изменено: TSN - 18.02.2021 16:15:23
 
TSN
Громаднейшее вам СПАСИБО!!!! Решение вполне рабочее!
Подробнее в ЛС
Потом все же попытаюсь разобраться в вашем коде и как такое вообще делается.
 
чего-то я совсем про эту тему позабыл ...
собственно, те самые пляски с бубномjQuery, во вложении 2 reg файла для внесения необходимых для работы запроса изменений в реестр, и батник для снятия бэкапа перед изменением реестра. Если пользователь обладает правами администратора то должно быть достаточно импорта файла HKCU IE11.reg , иначе придется импортировать файл HKLM IE11.reg из-под администратора
Код
// Запрос1
let
    url    = "https://meteoinfo.ru/forecasts/russia/vologda-area/vologda",
    Source =  Web.Page("<script>
                  try {
                      d = document;
                      let w = window.open('', '_blank'),
                          wnd = new ActiveXObject('Shell.Application').windows(),
                          ie = wnd.Item(wnd.count - 1);
                      ie.navigate('"&url&"');
                      while (ie.LocationURL !== '"&url&"' ? true : ie.Document.readyState !== 'complete') {}
                      let $ = ie.Document.parentWindow.jQuery.noConflict();
                      $('.fc_short_img').replaceWith(function() {
                          return this.title
                      });
                      $('.fc_small_gorizont_ww span').replaceWith(function() {
                          return this.title + this.innerText
                      });
                      d.write($('.fc_tab_1')[0].outerHTML);
                      ie.Application.Quit();
                  } catch (e) {
                      d.write('<table><tr><th>error<tr><td>' + e.message)
                  }
                  delete d;
              </script>"){0}[Data],
    Custom1 = Table.ReplaceValue(Source,{"День","Ночь"},"Характер погоды",(a,b,c)=>if List.Contains(b,a) then c else a,{"Column1"}),
    Custom2 = Table.FromColumns({{"Время суток"}&List.Combine(List.Transform({"День","Ночь"},each List.Repeat({_},5)))}&Table.ToColumns(Custom1)),
    Custom3 = Table.PromoteHeaders(Custom2, [PromoteAllScalars=true]),
    Custom4 = Table.RenameColumns(Custom3,{{"", "Показатель"}}),
    Custom5 = Table.UnpivotOtherColumns(Custom4, {"Время суток", "Показатель"}, "Дата", "Значение"),
    Custom6 = Table.TransformColumns(Custom5,{{"Дата", each Date.FromText(Text.AfterDelimiter(_,"#(cr,lf)")), type date}})
in
    Custom6
Страницы: 1
Наверх