Как очистить данные с веб-страницы с помощью SAS

Постановка проблемы: мне нужно получить данные из Интернета и поместить их в набор данных SAS с помощью программы SAS.

Сработало хорошо: я могу получить содержимое целевой веб-страницы с помощью SAS.

Не работает (нужна помощь): мне не удается обработать исходное содержимое страницы (показано ниже) с помощью SAS. Мне нужно найти категорию в исходном контенте и, если она найдена, получить все значения для этой строки (NOV, OCT, SEP, AUG, JUL). Точно так же мне нужно найти Conference Board в исходном контенте и, если он найден, получить все значения для этой строки (96,1,101,4,101,3,86,3,91,7). Ожидается, что структура исходного контента всегда останется неизменной. Ожидаемый результат прилагается в виде png-изображения. Было бы здорово узнать и помочь, если бы кто-то знал и помог мне, как справиться с этим сценарием с помощью программы SAS.

Я пробовал что-то вроде этого:

filename output "/desktop/Response.txt";

proc http           
url="http://hosting.briefing.com/cschwab/Calendars/EconomicReleases/conf.htm"       
method="get"        
proxyhost="&proxy_host."        
proxyport=&port         
out=output;     
run;

DATA CHECK;
LENGTH CATEGORY $ 5;
RETAIN CATEGORY;
INFILE output LENGTH = recLen LRECL = 32767;
INPUT line $VARYING32767. recLen;
IF FIND(line,'Category') GT 0 THEN DO;
CATEGORY = SCAN(STRIP(line),2,'<>');
OUTPUT;
END;
RUN;

Исходный контент веб-страницы:

<table width="100%" cellpadding="2" cellspacing="0" border="0">
  <tr valign="top" align="right" class="sectionColor">
    <td class="rH" align="left">Category</td>
    <td class="rH">NOV</td>
    <td class="rH">OCT</td>
    <td class="rH">SEP</td>
    <td class="rH">AUG</td>
    <td class="rH">JUL</td>
  </tr>
  <tr valign="top" align="right" class="sectionColor">
    <td class="rD" align="left">Conference Board</td>
    <td class="rD">96.1</td>
    <td class="rD">101.4</td>
    <td class="rD">101.3</td>
    <td class="rD">86.3</td>
    <td class="rD">91.7</td>
  </tr>
 <tr valign="top" align="right" class="sectionColor">
    <td class="rL" align="left">&nbsp;&nbsp;Expectations</td>
    <td class="rL">89.5</td>
    <td class="rL">98.2</td>
    <td class="rL">102.9</td>
    <td class="rL">86.6</td>
    <td class="rL">88.9</td>
  </tr>
  <tr valign="top" align="right" class="sectionColor">
    <td class="rD" align="left">&nbsp;&nbsp;Present Situation</td>
    <td class="rD">105.9</td>
    <td class="rD">106.2</td>
    <td class="rD">98.9</td>
    <td class="rD">85.8</td>
    <td class="rD">95.9</td>
  </tr>
  <tr valign="top" align="right" class="sectionColor">
    <td class="rL" align="left">Employment  ('plentiful' less 'hard to get')</td>
    <td class="rL">7.2</td>
    <td class="rL">7.1</td>
    <td class="rL">3.3</td>
    <td class="rL">-2.2</td>
    <td class="rL">2.2</td>
  </tr>
  <tr valign="top" align="right" class="sectionColor">
    <td class="rD" align="left">1 yr inflation expectations</td>
    <td class="rD">5.7%</td>
    <td class="rD">5.6%</td>
    <td class="rD">5.7%</td>
    <td class="rD">5.8%</td>
    <td class="rD">6.1%</td>
  </tr>
</table>

Вывод набора данных SAS должен быть таким:


person anil kumar    schedule 30.11.2020    source источник
comment
Вы упускаете ожидаемый результат. Пожалуйста, включите любой код, который вы использовали для анализа файла до сих пор.   -  person Reeza    schedule 30.11.2020


Ответы (3)


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

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

Пример:

filename output temp;

proc http           
url="http://hosting.briefing.com/cschwab/Calendars/EconomicReleases/conf.htm"       
method="get"        
/*proxyhost="&proxy_host."        */
/*proxyport=&port         */
out=output;     
run;

data have_cells (keep=row_num name value);
  length name value $32;

  infile output _infile_=line;
  input;

  retain landmark_found 0 table_found 0 naming 1 in_row 0 row_num -1;

  if not landmark_found then  
    landmark_found = prxmatch('/Highlights/',  line);

  if not landmark_found then
    delete;

  if not table_found then
    table_found = prxmatch('/<table /', line);

  if not table_found then
    delete;

  array names(20) $8 _temporary_;

  if not in_row then
    if prxmatch('/<tr /', line) then do;
      col_index = 0;
      in_row = 1;
      row_num + 1;
      return;
    end;

  if not in_row then
    delete;
td:
  rxtd = prxparse('/<td .*?>(.*)<\/td>/');
  if prxmatch(rxtd, line) then do;
    col_index + 1;
    if naming then do;
      names(col_index) = prxposn(rxtd,1,line);
    end;
    else do;
      name = names(col_index);
      value = prxposn(rxtd,1,line);
      OUTPUT;
    end;
    return;
  end;

  in_row = not prxmatch('/<\/tr/', line);

  if naming then if not in_row then naming = 0;

  if prxmatch('/<\/table>/', line) then stop;
run;

proc transpose data=have_cells out=have_raw;
  by row_num;
  id name;
  var value;
run;

введите здесь описание изображения

Вам придется выполнить больше кодирования для

  • htmldecode() определенные столбцы
  • столбцы символов нужного размера
  • convert others
    • character to numeric
    • персонаж на сегодняшний день
person Richard    schedule 30.11.2020
comment
Большой ! Это работает. Спасибо Ричард!! - person anil kumar; 01.12.2020

ЕСЛИ (и это БОЛЬШОЕ, если с HTML-страницами) файл остается таким же аккуратным, как в этом примере, вы можете довольно легко его проанализировать. Просто найдите теги <table>, <tr> и <td>. Сделайте свои собственные счетчики для номера таблицы, номера строки, номера столбца.

filename output url 
  "http://hosting.briefing.com/cschwab/Calendars/EconomicReleases/conf.htm"
;

data tall;
 length table row col 8 value $200;
 infile output truncover ;
 do until(left(_infile_)=:'<table'); input ; end;
 table+1;
 row=0;
 do until(left(_infile_)=:'</table');
   input;
   if left(_infile_)=:'<tr' then do; row+1; col=0; end;
   if left(_infile_)=:'<td' then do; 
      value = left(scan(_infile_,-2,'<>')); 
      col+1; 
      if value ne ' ' then output; 
   end;
 end;
run;

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

proc transpose data=tall out=tables(drop=_name_) prefix=col;
  where table=2;
  by table row;
  id col;
  var value;
run;

введите здесь описание изображения

Но вы, вероятно, захотите транспонировать это. Поэтому пересортируйте перед шагом PROC TRANSPOSE.

proc sort data=tall;
  by table col row;
run;
proc transpose data=tall out=tables(drop=_name_) prefix=col;
  where table=2;
  by table col;
  id row;
  var value;
run;

Результаты введите здесь описание изображения

person Tom    schedule 30.11.2020
comment
Том, код очень четкий! Работает блестяще! Большое спасибо ! - person anil kumar; 01.12.2020

Хотя SAS, к сожалению, не имеет абсолютно лучших доступных вариантов синтаксического анализа HMTL, у вас есть несколько вариантов, которые могут работать без синтаксического анализа с нуля.

Во-первых, вы можете иногда обрабатывать правильно сформированный HTML как XML. Ваш достаточно хорошо сформирован, чтобы почти сделать это; единственная проблема — это   и отсутствие тега в начале, что легко исправить.

Обычно лучший способ сделать это — скопировать текст в файл, а затем открыть утилиту SAS XML Mapper. Это позволит вам получить сообщения журнала, которые сообщат вам, что с ним не так, чтобы вы могли это исправить.

После того, как вы исправили все мелкие проблемы, вы можете просто использовать:

filename xml_file '<your html-as-xml file path>';

filename map temp;
  
libname xml_file xmlv2 automap=replace xmlmap=map;

Затем эту карту можно использовать для дальнейшего анализа документа. Это дает вам libname xml_file, который затем имеет таблицу членов, tr и td, которые вы можете связать друг с другом, используя порядковые номера (в основном, значения индекса с автоматическим приращением).

Ваш второй вариант, который я бы порекомендовал в большинстве случаев, — передать синтаксический анализ на какой-то другой язык. В Python есть отличный синтаксический анализатор BeautifulSoup, который в SAS 9.4 TS1M6 можно использовать изнутри SAS через механизм FCMP; или, если вы знакомы с Groovy, PROC GROOVY также неплохо справляется с разбором HTML. Вы можете либо написать отдельную программу на другом языке, либо интегрировать их; SAS хорошо интегрируется с несколькими языками (начнем с Python и R, оба из которых имеют хорошие синтаксические анализаторы).

person Joe    schedule 01.12.2020
comment
Спасибо за блестящие предложения Джо !! - person anil kumar; 01.12.2020