Есть HTML - как я могу получить данные из его таблиц, используя xpath - PullRequest
0 голосов
/ 08 мая 2018

Используя selenium для перехода на страницу, войдите в систему, запустите скрипт, который заполняет таблицу результатов поиска. Я использую это, чтобы получить код innerHTML. Сейчас я пытаюсь использовать xpath, чтобы получить фактические данные из таблицы, но я застрял.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from lxml import html
from lxml import etree
import requests

browser = webdriver.Chrome() 
url = "www.url.com"
browser.get(url) 

username = browser.find_element_by_id("username") #username form field
password = browser.find_element_by_id("password") #password form field

username.send_keys("myusername")
password.send_keys("mypassword")
password.send_keys(Keys.RETURN)

Далее я перехожу на интересующую меня страницу и получаю innerHTML

browser.get('a different url')
innerHTML= browser.execute_script('return document.body.innerHTML')
tree = html.fromstring(innerHTML)

Есть таблица, которая имеет

<tbody id='searchResultsPage'>
<tr>
<td>...</td>
<td>...</td>
</tr>
...

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

thisItem = tree.xpath('//tbody[id="searchResultsPage"]/tr[position()=9]/td[position()=3]/text()')
print(thisRow)

Я ничего не получил.

Я также заметил, что один из столбцов представляет собой набор ссылок с классом «запись вида действия». Поэтому я попробовал следующее:

companies = tree.xpath('//a[@class="action-view-record"]/text()')
print(companies)

И это работает (хотя не решает мою первоначальную проблему, так как оставшиеся столбцы - просто теги). Но почему-то это работает только иногда. Примерно в 50% случаев код ничего не возвращает, в остальное время он возвращает правильные данные (список компаний).

Есть мысли о том, как ориентироваться в таблице? а почему иногда код ломается?

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

Я бы попробовал что-то вроде:

table_rows = driver.find_elements_by_xpath("//table[@id='table_id']//tr")

for row in rows:
    row_columns = row.find_element_by_xpaths('//tr')
    for column in columns:
        do_something_with_column_text(column.text)

table_rows будет в конечном итоге список всех строк таблицы, которые имеют родительскую таблицу с идентификатором «table_id». Затем будет перебирать каждый столбец каждой строки.

0 голосов
/ 08 мая 2018

Если у вас есть эта таблица:

<table id='searchResultsPage'>
<tr>
<td>...</td>
<td>...</td>
</tr>
</table>

Извлеките его с помощью регулярного выражения <table[^>]*>[\s\S]*?<\/table>\s*

Таким образом:

import xml.etree.ElementTree as ET
import re

htmltable = re.findall(r'<tbody[^>]*>[\s\S]*?<\/tr>\s*', htmldoc)

table = ET.XML(htmltable[0])
rows = iter(table)
headers = [col.text for col in next(rows)]

print headers

Вы получите:

['...', '...']

Тогда, в зависимости от сложности стола, вы можете сделать:

listtable = []

for row in rows:
    values = [col.text for col in row]
    listtable.append(dict(zip(headers, values)))

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