2015-06-06 2 views
0

У меня есть HTML в виде QByteArray, и я хотел бы его разобрать.Почему QWebFrame опускает значительную часть моего HTML?

QWebPage webpage; 
webpage.mainFrame()->setContent(html); 
QWebElementCollection elements = webpage.mainFrame()->findAllElements("div"); 

Однако, оказывается пустым, даже если HTML имеет много <div> с.

Если я печатаю qDebug() << webpage.mainFrame()->toHtml(); все, что я вижу, это "<html><head></head><body></body></html>" anthough в html есть хорошая большая страница с заголовком, телом, таблицами и содержимым.

Если я использую setHtml вместо setContent путем преобразования html в QString, я Литт немного больше, но не намного. Если я печатаю qDebug() << webpage.mainFrame()->toHtml();, я вижу заголовок с его содержимым, но без таблиц стилей, но тело полностью опущено. Она заканчивается "...</head></html>"

ответ

1

Для большого содержания, структура DOM не может быть доступна только после звонков setContent или setHtml, вы должны позволить запустить цикл обработки событий и ждать сигнала QWebPage::loadFinished(), прежде чем делать что-либо на DOM (и даже то, если есть javascript, последний DOM еще не будет там).

Вы можете использовать QEventLoop или петлю с QCoreApplication::processEvents(), чтобы ждать сигнала в той же функции. Например:

QWebPage webpage; 

QEventLoop loop; 
// The signal is connected with Qt::QueuedConnection, 
// so that the loadFinished signal always trigger the quit() slot 
// even if the loop wasn't needed 
QObject::connect(&webpage, SIGNAL(loadFinished(bool)), &loop, SLOT(quit()), 
       Qt::QueuedConnection); 
webpage.mainFrame()->setContent(html); 

loop.exec(); 

QWebElementCollection elements = webpage.mainFrame()->findAllElements("div"); 
+0

Я думал, что это происходит только тогда, когда я использую 'нагрузки()', чтобы получить страницу с внешнего (веб) ресурса. Теперь он работает, если я жду сигнала 'loadFinished'. Теперь все имеет смысл, изначально «setHtml», вероятно, загружен чуть больше, чем 'setContent' из-за преобразования из' QString'. – vsz

+0

@vsz Я изменил код: сигнал был испущен, но слот quit() был вызван синхронно, прежде чем exec() успел запустить. Соединив слот перед вызовом setContent и используя 'Qt :: QueuedConnection', вызов слота задерживается до тех пор, пока цикл не будет запущен (из-за этого я не уверен, есть ли тривиальное решение для больших и небольшое содержимое с помощью 'processEvents'). – alexisdm

+0

Для большего размера файла отдельный поток, вероятно, будет лучшим решением, но это простое и элегантное решение теперь работает и достаточно для решения этой задачи. Спасибо за ваше время! – vsz

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