【问题标题】:Python - Read tablePython - 读取表格
【发布时间】:2016-10-20 23:27:43
【问题描述】:

在 python 中使用 lxml 库我如何读取 html 表的 td 值?我尝试阅读 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> 

【问题讨论】:

  • 你知道如何使用 xpath 吗?
  • 不是真的,我找不到任何好的文档。我很想获取 tr align="right" 之后的所有 td 值,但我无法正确获取语法。
  • w3schools.com/xml/xpath_intro.aspxpath("//table/tr[@align='right']/td")
  • @PadraicCunningham 谢谢。我如何将其转换为字符串值。它显示为这样的元素列表.....=> [0]: [1]: [2]: [3] :
  • 只需使用xpath("//table/tr[@align='right']/td/text()")提取文本

标签: python html xpath web-scraping lxml


【解决方案1】:

如果你想在 tr's 中找到 td's 并使用 align right,你需要使用 align 属性进行 ti 过滤:

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]

【讨论】:

  • 你在开玩笑吗,你根据他的评论改变了答案?
  • @HishamKaram,我改了什么答案?此外,从 td 获取文本的正确方法不是 //text(),它会递归提取文本,正如我在回答中指出的那样,只需将所有文本拉入一个平面列表,它就会失去任何关联。
  • 我的意思是他只用了 2 个小时就更改了答案并编辑了问题,这是否足够公平?
  • @PadraicCunningham 有没有办法像 td 列表的前 10 个元素一样抓取,或者我必须遍历所有项目?
【解决方案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']

【讨论】:

  • 嘿,我的列表中有很多 \n 和其他垃圾。是不是因为我抓取的表格有样式属性。
  • 读取所有 tr align="right" 值的语法是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-02
  • 2021-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多