【问题标题】:How do I return a web page's table cell value without ID, using column and row names (not index)如何使用列名和行名(不是索引)返回没有 ID 的网页表格单元格值
【发布时间】:2016-03-26 22:07:04
【问题描述】:

关于 Python 和 Selenium 抓取网页表格数据的大多数问题都涉及带有 ID 或类的表格,以及一些使用行数和列数的索引技术。 Xpath 技术通常也不解释。

假设我有一个没有元素 ID 或类的表,我们以 this one 为例。

我想返回值“Johnson”,而不计算行号或列号。

这是我的尝试(已编辑)...

import selenium.webdriver as webdriver
import contextlib
url = 'http://www.w3schools.com/html/html_tables.asp'

with contextlib.closing(webdriver.Firefox()) as driver:
    driver.get(url)
    columnref = 3
    rowref = 4
    xpathstr = '//tr[position()=' + str(rowref) + ']//td[position()=' + str(columnref) + ']'
    data = driver.find_element_by_xpath(xpathstr).text
print data

我已经在这里得到了一些很好的帮助,但我仍在使用索引。我需要通过查找它们的值来生成“columnref”和“rowref”。分别是“姓氏”和“3”。

【问题讨论】:

  • 这不是xpath 的正确形式。为您的表格提供html 部分代码
  • @Andersson - 干杯我更新了问题:)
  • @drets 这不是很好。好吧,我没有标记它,希望这个人这样做。与此同时,我正在为自己解决剩下的问题,而不是抱怨有人只为我完成了 75% 的工作。
  • 问题已被投票;-)

标签: python-2.7 selenium xpath


【解决方案1】:
In [1]: run table_cell_value.py
Johnson

table_cell_value.py

from selenium import webdriver

browser = webdriver.Firefox()

COLUMN_NAME = 'Last Name'
ROW_NAME = '3'

JS_SCRIPT = """
var row = column = -1;
var table = arguments[0];

for (var c = 0, m = table.rows[0].cells.length; c < m; c++) {
    if (table.rows[0].cells[c].innerHTML === arguments[1]) {
        column = c
    }
}

for (var r = 0, n = table.rows.length; r < n; r++) {
    if (table.rows[r].cells[0].innerHTML === arguments[2]) {
        row = r
    }
}

if (row < 0 || column < 0) {
    return
}

return table.rows[row].cells[column].innerHTML
"""


browser.get('http://www.w3schools.com/html/html_tables.asp')
table = browser.find_element_by_tag_name('table')
print browser.execute_script(JS_SCRIPT, table, COLUMN_NAME, ROW_NAME)

文档:https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement

【讨论】:

  • 谢谢,但是我们为什么要给我们js呢?
  • @drets 我添加了缺失部分的代码。检查我的答案
【解决方案2】:

只需使用此 css 选择器即可到达您想要的单元格tbody &gt; tr:nth-child(4) &gt; td:nth-child(3),您可以使用相同的方式为任何单元格生成 css 选择器。见下文:

>>> driver.find_element_by_css_selector("tbody > tr:nth-child(4) > td:nth-child(3)")
<selenium.webdriver.remote.webelement.WebElement object at 0x10fdd4510>
>>> driver.find_element_by_css_selector("tbody > tr:nth-child(4) > td:nth-child(3)").text
u'Johnson'

或者,您可以使用position() 标签来定位单元格位置。见下文:

>>> driver.find_element_by_xpath("//tr[position()=4]//td[position()= 3]").text
u'Johnson'
>>> driver.find_element_by_xpath("//tr[position()=5]//td[position()= 3]").text
u'Smith'

如果您想通过 列名行号 获取文本,您可以编写一个函数,通过查找列的索引然后获取文本来返回值如下:

def get_text_column_row(table_css, header, row):
    table = driver.find_element_by_css_selector(table_css)
    table_headers = table.find_elements_by_css_selector('tbody > tr:nth-child(1) > th')
    table_rows = table.find_elements_by_css_selector("tbody > tr > td:nth-child(1)")

    index_of_column = None
    index_of_row = None

    for i in range(len(table_headers)):
        if table_headers[i].text == header:
            index_of_column = i + 1

    for i in range(len(table_rows)):
        if table_rows[i].text == row:
            index_of_row = i + 1

    xpath = '//tr[position() = %d]//td[position() = %d]' %(index_of_row, index_of_column)

    return driver.find_element_by_xpath(xpath).text 

并像下面这样使用它:

>>> get_text_column_row('#main > table:nth-child(6)', 'Points', '3')
u'80'
>>> get_text_column_row('#main > table:nth-child(6)', 'Last Name', '3')
u'Doe'
>>> get_text_column_row('#main > table:nth-child(6)', 'Last Name', '4')
u'Johnson'

【讨论】:

  • 我以为你右键单击检查器和表格主体的“复制唯一选择器”。你是如何得到你的以供将来参考的?
  • 另外,这是使用索引。如何使用列名和行标识符返回文本?
  • 5 年前我就是这样做的 :) 。它只是一个简单的 CSS 选择器。
  • @square_eyes 的问题现在更清楚了。让我检查一下。
  • 这很有帮助,但是如何使用列名和行名而不是​​索引返回?谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-28
  • 2022-08-20
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多