2015-02-21 2 views
1

Я пытаюсь разобрать веб-страницу, содержащую это:Синтаксический XPath с питоном

<table style="width: 100%; border-top: 1px solid black; border-bottom: 1px solid black;"> 
<tr> 
<td colspan="2" 
    style="border-top: 1px solid black; border-bottom: 1px solid black; background-color: #f0ffd3;">February 20, 2015</td> 
</tr> 
<tr> 
<td style="border-top: 1px solid gray; font-weight: bold;">9:00 PM</td> 
<td style="border-top: 1px solid gray; font-weight: bold">14°F</td> 
</tr> 
<tr> 
<td style="border-bottom: 1px solid gray;">Clear<br /> 
    Precip: 
    0 %<br /> 
           Wind: 
        from the WSW at 6 mph 
</td> 
<td style="border-bottom: 1px solid gray;"><img class="wxicon" src="http://i.imwx.com/web/common/wxicons/31/31.gif" 
     style="border: 0px; padding: 0px 3px" /></td> 
</tr> 
<tr> 
<td style="border-top: 1px solid gray; font-weight: bold;">10:00 PM</td> 
<td style="border-top: 1px solid gray; font-weight: bold">13°F</td> 
</tr> 
<tr> 
<td style="border-bottom: 1px solid gray;">Clear<br /> 
    Precip: 
    0 %<br /> 
           Wind: 
        from the WSW at 6 mph 
</td> 
<td style="border-bottom: 1px solid gray;"><img class="wxicon" src="http://i.imwx.com/web/common/wxicons/31/31.gif" 
     style="border: 0px; padding: 0px 3px" /></td> 
</tr> 

(он продолжает с большим количеством строк и заканчивается [/ таблица]

tree = html.fromstring(page) 
table = tree.xpath('//table/tr') 
for item in table: 
    for elem in item.xpath('*'): 
     if 'colspan' in html.tostring(elem): 
       print '*', elem.text 
     elif elem.text is not None: 
      print elem.text, 
     else: 
      print 

несколько работает. Он не получает текст, следующий за [br /], и это далеко не изящно. Как получить недостающий текст? Кроме того, будут оценены любые предложения по улучшению кода.

ответ

2

Как насчет использования .text_content()?

.text_content(): Возвращает текстовое содержимое элемента, включая текстовое содержание своих детей, без разметки.

table = tree.xpath('//table/tr') 
for item in table: 
    print ' '.join(item.text_content().split()) 

join() + split() здесь поможет заменить несколько пробелов с одного.

Он печатает:

February 20, 2015 
9:00 PM 14°F 
Clear Precip: 0 % Wind: from the WSW at 6 mph 
10:00 PM 13°F 
Clear Precip: 0 % Wind: from the WSW at 6 mph 

Поскольку вы хотите объединить тайм-линию с засветкой линией, вы можете перебрать tr тегов, но пропуская те, которые содержат Precip в тексте. Для каждой временной линии, получаем следующую тр родственный, чтобы получить засветки линию:

table = tree.xpath('//table/tr[not(contains(., "Precip"))]') 
for item in table: 
    text = ' '.join(item.text_content().split()) 
    if 'AM' in text or 'PM' in text: 
     text += ' ' + ' '.join(item.xpath('following-sibling::tr')[0].text_content().split()) 

    print text 

Печать:

February 20, 2015 
9:00 PM 14°F Clear Precip: 0 % Wind: from the WSW at 6 mph 
10:00 PM 13°F Clear Precip: 0 % Wind: from the WSW at 6 mph 
+0

Гораздо приятнее! Есть ли хороший способ определить, является ли строка линией даты, временной линией или другой строкой (с использованием xpath, а не для разбора содержимого)? Если ничего другого, я бы хотел объединить каждую линию времени с ее чистой линией прохода. – foosion

+0

@foOSion для строки даты - я бы выполнил принцип EAFP и попытался загрузить содержимое с помощью 'datetime.strptime()' и обработать 'ValueError' - если нет ошибки - это строка даты. На временной линии я думаю, что вы можете просто искать слово «PM» или «AM» внутри содержимого. Похоже, что другие линии начинаются с «Clear Precip». – alecxe

+0

@foosion позвольте мне предоставить вам образец, дайте мне минуту. – alecxe

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