2009-10-16 2 views
5

Я новичок в LXML, совершенно новый для питона и не смог найти решение следующего:питона, LXML и XPath - HTML таблицы синтаксического анализ

Мне нужно импортировать несколько таблиц с 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?

Заранее спасибо за вашу помощь, Алекс

+0

Не могли бы вы вставить исходный документ (или часть) и ожидаемый результат? Я не эксперт в python, но я хорошо разбираюсь в xpath, и я думаю, что смогу вам помочь. – prostynick

+0

исходный документ доступен здесь (только между 06 ч. 00 м. И 22 ч. 00 м.): http://tinyurl.com/yj4corh – user191131

+0

ожидаемый результат: [['Premier', '05', 'name1'], [u'Deuxi \ xe8me ',' 13 ',' name2 ']] – user191131

ответ

0

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

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

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

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

Update: Если вам нужно только 3-й строки и на, используйте data[2:]

+0

Спасибо, вложенный цикл и добавление вызова list() действительно сделали трюк. Но он по-прежнему не работает со вторым xpath, который мне нужен (я думаю) – user191131

+0

Мне непонятно, зачем вам второй xpath, см. Обновление к моему ответу. – interjay

+0

Мне нужно все содержимое таблицы, начиная с строки 3, а второй xpath возвращает только одну строку. Конечно, я сделал то, что вы предложили в своем обновлении, но мне любопытно узнать, что не так со вторым xpath, так как это сделает мой код на следующие дни более чистым. – user191131

2

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

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] в конце, что вас забивает.

+0

Спасибо за ваш ответ. Но удаление [0] в конце xpath вызывает exeption: AttributeError: объект «list» не имеет атрибута «xpath» – user191131

+0

Я не считаю, что просто удаление '[0]' из конца этого утверждения вызвало ошибка. Вы изменили что-то еще, или ошибка возникает позже. –

+0

Простите, что бедная душа, я должен признать, что мои навыки python очень вероятно вовлечены ... Вот фактический фрагмент кода, который меня прослушивает: http://pastebin.com/m522b6970 – user191131

Смежные вопросы