PyQt4 to PyQt5 -> mainFrame() устарел, необходимо исправить, чтобы загрузить веб-страницы

Я делаю Sentdex PyQt4 YouTube учебник прямо здесь. Я пытаюсь следовать, но вместо этого использую PyQt5. Это простое веб-приложение. Я последовал вместе с руководством Sentdex и попал сюда:

введите описание изображения здесь

Сейчас я пытаюсь написать то же самое приложение с PyQt5, и вот что у меня есть:

import os
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from bs4 import BeautifulSoup
import requests


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

    def _loadFinished(self):
        self.app.quit()


url = 'https://pythonprogramming.net/parsememcparseface/'
client_response = Client(url)

#I think the issue is here at LINE 26
source = client_response.mainFrame().toHtml()

soup = BeautifulSoup(source, "html.parser")
js_test = soup.find('p', class_='jstest')
print(js_test.text)

Когда я запускаю это, я получаю сообщение:

source = client_response.mainFrame().toHtml()
AttributeError: 'Client' object has no attribute 'mainFrame'

Я пробовал несколько разных решений, но ни одно из них не работает. Любая помощь будет оценена.

РЕДАКТИРОВАТЬ

Регистрация QUrl(url) в строке 15 возвращает это значение:

PyQt5.QtCore.QUrl('https://pythonprogramming.net/parsememcparseface/')

Когда я пытаюсь source = client_response.load(QUrl(url)) для строки 26 я получаю сообщение:

File "test3.py", line 28, in <module> soup = BeautifulSoup(source, "html.parser") File "/Users/MYNAME/.venv/qtproject/lib/python3.6/site-packages/bs4/__init__.py", line 192, in __init__ elif len(markup) <= 256 and ( TypeError: object of type 'NoneType' has no len()

Когда я пытаюсь source = client_response.url() Я получил:

soup = BeautifulSoup(source, "html.parser")
      File "/Users/MYNAME/.venv/qtproject/lib/python3.6/site-packages/bs4/__init__.py", line 192, in __init__
        elif len(markup) <= 256 and (
    TypeError: object of type 'QUrl' has no len()

2 ответа

Вы должны позвонить QWebEnginePage::toHtml() внутри определения класса. QWebEnginePage::toHtml() принимает функцию указателя или лямбду в качестве параметра, и эта функция указателя должна, в свою очередь, принимать параметр типа 'str' (это параметр, который содержит html страницы). Вот пример кода ниже.

import bs4 as bs
import sys
import urllib.request
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl

class Page(QWebEnginePage):
    def __init__(self, url):
        self.app = QApplication(sys.argv)
        QWebEnginePage.__init__(self)
        self.html = ''
        self.loadFinished.connect(self._on_load_finished)
        self.load(QUrl(url))
        self.app.exec_()

    def _on_load_finished(self):
        self.html = self.toHtml(self.Callable)
        print('Load finished')

    def Callable(self, html_str):
        self.html = html_str
        self.app.quit()


def main():
    page = Page('https://pythonprogramming.net/parsememcparseface/')
    soup = bs.BeautifulSoup(page.html, 'html.parser')
    js_test = soup.find('p', class_='jstest')
    print js_test.text

if __name__ == '__main__': main()

Никогда не поздно... Я получил ту же проблему и нашел ее описание здесь: http://pyqt.sourceforge.net/Docs/PyQt5/gotchas.html

Я последовал совету поместить QApplication в глобальную переменную (я знаю, что он грязный... и я буду наказан за это), и он работает "отлично". Я могу зациклить без какого-либо сбоя.

Надеюсь, это поможет.

Другие вопросы по тегам