python, lxml и xpath – html разбор таблицы

Я новичок в lxml, совершенно новый для python и не нашел решения для следующего:

Мне нужно импортировать несколько таблиц с 3 столбцами и неопределенное количество строк, начиная со строки 3.

Когда второй столбец любой строки пуст, эта строка отбрасывается и обработка таблицы прерывается.

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

from lxml.html import parse def process_row(row): for cell in row.xpath('./td'): print cell.text_content() yield cell.text_content() def process_table(table): return [process_row(row) for row in table.xpath('./tr')] doc = parse(url).getroot() tbl = doc.xpath("/html//table[2]")[0] data = process_table(tbl) 

Это печатает только первый столбец 🙁

 for i in data: print i.next() 

Следующие только импортируют третью строку, а не следующую

 tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0] 

Кто-нибудь знает модное решение, чтобы получить все данные из строки 3 в tbl и скопировать его в массив, чтобы его можно было обработать в модуле без зависимости lxml?

Заранее благодарим за помощь, Алекс

  • Lxml html xpath context
  • XPath: выберите тег с пустым значением
  • Найти элемент по тексту с помощью XPath в ElementTree
  • Как я могу щелкнуть кнопку в форме с помощью Selenium и Python 2.7?
  • Xpath vs DOM vs BeautifulSoup vs lxml vs other Какой самый быстрый подход к анализу веб-страницы?
  • Scrapy: динамически генерировать правила для каждого start_url
  • Создание цикла для анализа данных таблицы в scrapy / python
  • Python Selenium: найти атрибуты объекта с помощью xpath
  • 2 Solutions collect form web for “python, lxml и xpath – html разбор таблицы”

    Это генератор:

     def process_row(row): for cell in row.xpath('./td'): print cell.text_content() yield cell.text_content() 

    Вы называете это так, как будто считаете, что он возвращает список. Это не так. Существуют контексты, в которых он ведет себя как список:

     print [r for r in process_row(row)] 

    но это только потому, что генератор и список отображают один и тот же интерфейс for циклов. Используя его в контексте, где он получает оценку только один раз, например:

     return [process_row(row) for row in table.xpath('./tr')] 

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

    Так что это твоя первая проблема. Ваш второй – то, что вы ожидаете:

     tbl = doc.xpath("//body/table[2]//tr[position()>2]")[0] 

    чтобы дать вам третий и все последующие строки, и это только установка tbl в третью строку. Ну, вызов xpath возвращает третью и все последующие строки. Это [0] в конце концов, это беспорядок.

    Вы должны использовать цикл для доступа к данным строки, например:

     for row in data: for col in row: print col 

    Вызов next () один раз, как вы, будет иметь доступ только к первому элементу, поэтому вы видите один столбец.

    Обратите внимание, что из-за природы генераторов вы можете обращаться к ним только один раз. Если вы изменили вызов process_row(row) в list(process_row(row)) , генератор будет преобразован в список, который можно использовать повторно.

    Обновление: если вам нужна только 3-я строка и дальше, используйте data[2:]

    Python - лучший язык программирования в мире.