Python — Чтение таблицы

#python #html #xpath #web-scraping #lxml

#python #HTML #xpath #очистка веб-страниц #lxml

Вопрос:

В python с использованием библиотеки lxml как мне прочитать значения td в html-таблицах? Я попытался прочитать таблицу xpath, но не могу найти правильный параметр для возврата значений td. Спасибо всем, я ценю это.

 import sys
from glob import *
from lxml import etree, html
import requests
#Scan directory (current) and scrape the html files
dirScan = glob('html/*.*')
fileCount = 0
while(fileCount < len(dirScan)):
    fileName =  dirScan[fileCount]
    page = open(fileName)
    tree = html.fromstring(page.read())
   tables = tree.xpath('//table')
   print("Tables:",tables)
  

page.html

  <table style="width:100%">
 <tr align="right"><td>1</td><td>John</td><td>Smith</td>
 <tr align="right"><td>2</td><td>Tody</td><td>Miller</td>
</table> 
  

Комментарии:

1. Вы знаете, как использовать xpath?

2. Не совсем, и я не могу найти никакой хорошей документации по этому поводу. Я пытаюсь получить все значения td, которые находятся после tr align = «right», но я не могу получить правильный синтаксис.

3.w3schools.com/xml/xpath_intro.asp xpath("//table/tr[@align='right']/td")

4. @PadraicCunningham Спасибо. Как мне преобразовать это в строковые значения. Он отображается в виде списка элементов следующим образом…..=> [0]:< Элемент td в 0x7fee11ab2958> [1]: <Элемент td в 0x7fee11ac68b8> [2]: <Элемент td в 0x7fee11ac6908> [3]: <Элемент td в 0x7fee11ac6958>

5. Просто используйте xpath("//table/tr[@align='right']/td/text()") для извлечения текста

Ответ №1:

Если вы хотите найти td внутри tr с выравниванием по правому краю, вам нужен фильтр ti с использованием атрибута align:

 tds = tree.xpath("//table/tr[@align='right']/td")
  

Если вам просто нужен текст из каждого td:

 .xpath("//table/tr[@align='right']/td/text()")
  

Но на самом деле вы, вероятно, хотите сохранить ассоциацию, поэтому вам следует просто найти trs, а затем сгруппировать текст td:

 x = """<table style="width:100%">
 <tr align="right"><td>1</td><td>John</td><td>Smith</td>
 <tr align="right"><td>2</td><td>Tody</td><td>Miller</td>
</table> """

from lxml import html

tree = html.fromstring(x)

# first get the trs, filtering by attribute 
trs = tree.xpath("//table/tr[@align='right']")

# then extract the tds from each tr 
data = [row.xpath("td/text()") for row in trs]
  

Что дало бы вам:

 [['1', 'John', 'Smith'], ['2', 'Tody', 'Miller']]
  

И если бы вы просто хотели каждое имя, вы могли бы пропустить первый td:

 trs = tree.xpath("//table/tr[@align='right']")

# position() > 1, all but the first td, xpath has one based indexing.
names = [row.xpath("td[position()> 1]/text()") for row in trs])
  

Или объединение в одну строку:

  full_names [" ".join(row.xpath("td[position()> 1]/text()")) for row in trs]
  

Комментарии:

1. Вы издеваетесь надо мной, вы изменили ответ на основе его комментария 😡

2. @HishamKaram, я изменил какой ответ? Также правильный способ просто получить текст из td — это не //text() , он будет извлекать текст рекурсивно, и, как указано в моем ответе, он потеряет какую-либо связь, просто собрав весь текст в один плоский список.

3. я имею в виду, что он изменил ответ и отредактировал вопрос всего за 2 часа, достаточно ли это справедливо?

4. @HishamKaram, игнорируя любое редактирование, //text() неверно и даже tree.xpath('//tr/td/text()') , как я уже прокомментировал, дает вам список строк, которые не содержат ассоциаций.

5. @PadraicCunningham Есть ли способ, с помощью которого я могу захватить первые 10 элементов списка td, или мне нужно просмотреть все элементы?

Ответ №2:

код

  >>> page="""<table style="width:100%">
      <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Age</th>
      </tr>
      <tr>
        <td>1</td>
        <td>Smith</td>
        <td>50</td>
      </tr>
      <tr>
        <td>2</td>
        <td>Jackson</td>
        <td>94</td>
      </tr>
      <tr>
        <td>3</td>
        <td>Miller</td>
        <td>43</td>
      </tr>
    </table> """
    >>> tree=html.fromstring(s)
    >>> tree.xpath('//tr/td//text()')
  

вывод:

 ['1', 'Smith', '50', '2', 'Jackson', '94', '3', 'Miller', '43']
  

Комментарии:

1. Привет, в моем списке много n и другого мусора. Это потому, что таблица, которую я очищаю, имеет атрибуты стиля.

2. Каким был бы синтаксис для чтения всех значений tr align=»right»?