Стратегия извлечения структурированных данных с помощью xpath - PullRequest
1 голос
/ 27 марта 2011

Существует ли шаблон для извлечения структурированных данных со страницы HTML с использованием XPath? Я пытаюсь извлечь данные из одной или нескольких таблиц HTML на странице. XPath облегчает поиск таблиц, но я с трудом справляюсь, когда доберусь до этого.

В настоящее время я делаю следующее:

  • Перебор таблиц (их может быть больше одной)
  • Итерация строк в этой таблице
  • Перебрать ячейки в этой строке
  • (Затем, вероятно, поместите их в массив и проанализируйте содержимое)

Мой код выглядит примерно так:

var tables = mydoc.evaluate( "//table", mydoc, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null );

table = tables.iterateNext();
while (table)
{
  var rows = mydoc.evaluate("tbody/tr", table, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
  row = rows.iterateNext();
  while (row)
  {
    var tds = mydoc.evaluate("td", row, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)
    td = tds.iterateNext()
    while(td)
    {
      // TODO: store content in an array to process later
      print('*' + td.textContent);
      td = tds.iterateNext();
    }
    row = rows.iterateNext();
  }

  table = iterator.iterateNext();
}

Это кажется немного неприятным, поскольку все примеры XPath, похоже, выполняют их обработку за один шаг. Похоже, есть несколько нетривиальных примеров, когда два типа данных (например, метки и значения в таблице) выбираются и объединяются. Я могу использовать следующие селекторы, но в итоге получаю два списка без структуры:

//table/tbody/tr/td[@class='label']
//table/tbody/tr/td/a[@class='value']

(я знаю, что использую XPath для парсинга HTML, для которого он на самом деле не был предназначен, но, похоже, он пока работает.)

Ответы [ 2 ]

2 голосов
/ 27 марта 2011

Там, кажется, мало нетривиальных примеры, где два типа данных (например, метки и значения в таблице) выбрано и объединено. Я могу использовать следующие селекторы, но я в конечном итоге два списка без структуры:

//table/tbody/tr/td[@class='label'] 
//table/tbody/tr/td/a[@class='value']

Используйте

    //table/tbody/tr/td[@class='label']
|
    //table/tbody/tr/td/a[@class='value']

Это единственное выражение XPath выбирает все нужные узлы (все известные мне механизмы XPath возвращают выбранные узлы в порядке документа). Оператор | (union) создает объединение множеств своих аргументов.

Если (x) HTML-документ имеет регулярную структуру, в возвращаемом результате можно ожидать, что за каждым выбранным td элементом (меткой) будет следовать соответствующий a элемент (значение)

0 голосов
/ 31 декабря 2011

Если он находится на главной HTML-странице, вы можете просто сделать:

for(var tables=document.getElementsByTagName("table"),i=0;i<tables.length;++i)
  for(var rows=tables[i].getElementsByTagName("tr"),j=0;j<rows.length;++j)
    for(var cells=rows[j].getElementsByTagName("td"),k=0;k<cells.length;++k)
      print("*"+cells[i].textContent);

getElementsByTagName делает / не возвращает массив - он возвращает живой NodeList, похожий на ORDERED_NODE_ITERATOR_TYPE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...