2015-02-04 2 views
2

Я пытаюсь проанализировать данные с интерактивного веб-сайта google. Он отображается в JS, поэтому я использую Qt для загрузки сайта для анализа. Я считаю, что сайт загружен и обработан правильно, но по какой-то причине я получаю и пустой список, возвращенный мне, когда я выполняю код анализа xpath.Проблема с разбором html с lxml по xpath

Вот мой полный код:

import sys 
from PyQt4.QtGui import * 
from PyQt4.QtCore import * 
from PyQt4.QtWebKit import * 
from lxml import html 

class Render(QWebPage): 
    def __init__(self, url): 
    self.app = QApplication(sys.argv) 
    QWebPage.__init__(self) 
    self.loadFinished.connect(self._loadFinished) 
    self.mainFrame().load(QUrl(url)) 
    self.app.exec_() 

    def _loadFinished(self, result): 
    self.frame = self.mainFrame() 
    self.app.quit() 

url = 'https://www.consumerbarometer.com/en/graph-builder/?question=M1&filter=country:singapore,canada,mexico,brazil,argentina,united_states,bulgaria,austria,belgium,croatia,czech_republic,denmark,estonia,finland,france,germany,greece,hungary,italy,ireland,latvia,lithuania,norway,netherlands,poland,portugal,russia,romania,serbia,slovakia,spain,slovenia,sweden,switzerland,ukraine,united_kingdom,australia,china,israel,hong_kong_sar,japan,korea,new_zealand,malaysia,taiwan,turkey,vietnam' 
#This does the magic.Loads everything 
r = Render(url) 
#result is a QString. 
result = r.frame.toHtml() 

#QString should be converted to string before processed by lxml 
formatted_result = str(result.toAscii()) 

#Next build lxml tree from formatted_result 
tree = html.fromstring(formatted_result) 

archive_links = tree.xpath('//*[@id="main-page-wrapper"]/div/section/div/section[1]/div/div/graph/div/div[4]/div/div/graph-bar-chart/div[2]/svg/g[1]/g[2]/g[1]/text()') 
print archive_links 

Это HTML, что я пытаюсь схватить: <text class="bar-text-label" y="22" dy="10">Argentina</text>

Любые мысли, почему я получаю [] вернулся ко мне?

ответ

1

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

tree.xpath('//text[@class="bar-text-label"]/text()', namespaces={'n': 'http://www.w3.org/2000/svg'}) 

Альтернативное решение может быть использование selenium браузера пакет автоматизации:

from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 


driver = webdriver.Firefox() 
driver.get('https://www.consumerbarometer.com/en/graph-builder/?question=M1&filter=country:singapore,canada,mexico,brazil,argentina,united_states,bulgaria,austria,belgium,croatia,czech_republic,denmark,estonia,finland,france,germany,greece,hungary,italy,ireland,latvia,lithuania,norway,netherlands,poland,portugal,russia,romania,serbia,slovakia,spain,slovenia,sweden,switzerland,ukraine,united_kingdom,australia,china,israel,hong_kong_sar,japan,korea,new_zealand,malaysia,taiwan,turkey,vietnam') 

// wait for svg to appear 
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.TAG_NAME, 'svg'))) 

for text in driver.find_elements_by_class_name('bar-text-label'): 
    print(text.text) 

driver.close() 
+0

Я имел на самом деле просто попробовал более короткое выражение xpath выше и даже с добавлением пространства имен, я все равно получаю пустой список. – metersk

+0

@Meepl hm, я не пробовал использовать 'pyqt4', но я сохранил источник страницы в html-файле, проанализировал его с помощью' lxml.html' и использовал предоставленный xpath-работал для меня. Во всяком случае, вы согласитесь с альтернативным решением на основе «селена»? Благодарю. – alecxe

+0

есть, совершенно. У меня есть селен, но я совсем не знаком с ним. – metersk

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