Как получить веб-страницу с помощью pyqt5?

#javascript #python #pyqt5

#javascript #python #pyqt5

Вопрос:

Я хочу получить веб-страницу с помощью pyqt5 .

URL -это https://land.3fang.com/LandAssessment/b6d8b2c8-bd4f-4bd4-9d22-ca49a7a2dc1f.html .

Веб-страница сгенерирует два значения с помощью javascript.

Просто введите 5 в текстовое поле и нажмите красную кнопку.

Будут возвращены два значения красным цветом.

Пожалуйста, обратитесь к изображению.

Приведенный ниже код используется для получения веб-страницы.

Однако я долго жду, а ответа нет.

Что я должен изменить в своем коде?

Большое вам спасибо.

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

 import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from bs4 import BeautifulSoup
import pandas as pd

class Render(QWebEngineView):
    def __init__(self, url):
        self.html = None
        self.first_pass = True
        self.app = QApplication(sys.argv)
        QWebEngineView.__init__(self)
        self.loadFinished.connect(self._load_finished)
        self.load(QUrl(url))
        self.app.exec_()

    def _load_finished(self, result):
        if self.first_pass:
            self._first_finished()
            self.first_pass = False
        else:
            self._second_finished()

    def _first_finished(self):
        self.page().runJavaScript('document.getElementById("txtDistance").value = "5";')
        self.page().runJavaScript("void(0)")
        self.page().runJavaScript("CheckUserWhere();")

    def _second_finished(self):
        self.page().toHtml(self.callable)

    def callable(self, data):
        self.html = data
        self.app.quit()

url = "https://land.3fang.com/LandAssessment/b6d8b2c8-bd4f-4bd4-9d22-ca49a7a2dc1f.html"
web = Render(url)
soup = BeautifulSoup(web.html, 'html.parser')
element = soup.find('div', {'id':"divResult"})
df = pd.read_html(str(element))
  

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

Комментарии:

1. Нет, код не может выдать то, что я хочу.

Ответ №1:

Кажется, у вас есть несколько неправильных представлений:

  • При выполнении js страница не перезагружается, поэтому функция _second_finished никогда не будет вызвана.
  • Если вы не хотите показывать окно, тогда лучше использовать QWebEnginePage.

Учитывая вышесказанное, полученный html является:

 <div class="p8-5" id="divResult" style="display:block;">
<div align="center" display="block" id="rsloading" style="display: block;">
<img src="//img2.soufunimg.com/qyb/loading.gif"/>
                        正在为您加载数据...
                    </div>
<table border="0" cellpadding="0" cellspacing="0" class="tablebox01" display="none" id="tbResult" style="display: none;" width="600">
<tbody><tr>
<td style="width:260px;"><span class="gray8">建设用地面积:</span>14748平方米</td>
<td style="width:340px;"><span class="gray8">所在城市:</span>山西省 长治市 </td>
</tr>
<tr>
<td><span class="gray8">规划建筑面积:</span>51617平方米</td>
<td><span class="gray8">土地评估楼面价:</span><b class="redc00 font14" id="_bpgj">867.61</b> 元/平方米</td>
</tr>
<tr>
<td><span class="gray8">容积率:</span>大于1并且小于或等于3.5</td>
<td><span class="gray8">土地评估总价:</span><b class="redc00 font14" id="_bSumPrice">4478.34</b> 万元</td>
</tr>
<tr>
<td><span class="gray8">规划用途:</span>住宅用地</td>
<td><span class="gray8">推出楼面价:</span>27.51元/平方米</td>
</tr>
</tbody></table>
</div>
  

Итак, самое простое, что нужно сделать, это отфильтровать по идентификаторам «_bpgj» и «_bSumPrice»

 import sys
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
from bs4 import BeautifulSoup

class Render(QtWebEngineWidgets.QWebEnginePage):
    def __init__(self, url):
        self.html = ""
        self.first_pass = True
        self.app = QtWidgets.QApplication(sys.argv)
        super(Render, self).__init__()
        self.loadFinished.connect(self._load_finished)
        self.loadProgress.connect(print)
        self.load(QtCore.QUrl(url))
        self.app.exec_()

    def _load_finished(self, result):
        if result:
            self.call_js()

    def call_js(self):
        self.runJavaScript('document.getElementById("txtDistance").value = "5";')
        self.runJavaScript("void(0)")
        self.runJavaScript("CheckUserWhere();")
        self.toHtml(self.callable)

    def callable(self, data):
        self.html = data
        self.app.quit()

url = "https://land.3fang.com/LandAssessment/b6d8b2c8-bd4f-4bd4-9d22-ca49a7a2dc1f.html"
web = Render(url)
soup = BeautifulSoup(web.html, 'html.parser')
_bpgj = soup.find('b', {'id':"_bpgj"}).string
_bSumPrice = soup.find('b', {'id':"_bSumPrice"}).string
print(_bpgj, _bSumPrice)
  

Вывод:

 867.61 4478.34
  

Комментарии:

1. Я дважды запускал вашу программу и получил два результата: 0 70 100 Трассировка (последний последний вызов): Файл «C:program.py «, строка 277, в <module> _bpgj = soup.find(‘b’, {‘id’:»_bpgj»}).ошибка строкового атрибута: объект ‘NoneType’ не имеет атрибута ‘string’, а второй равен 0 22 70 100 — —

2. @Chan Может быть, у вас какой-то активированный прокси-сервер или какое-то другое ограничение или проблема в вашей сети, я протестировал его с последней версией pyqt5: 5.12.1 riverbankcomputing.com/software/pyqt/download5 и PyQtWebEngine: 5.12.1: riverbankcomputing.com/software/pyqtwebengine/download и это работает правильно. Попробуйте обновить свои библиотеки.

3. @Chan есть какие-нибудь отзывы?

4. Я удалил pyqt5 и pyqtwebengine, а затем переустановил их. С from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets сейчас нет никаких проблем. Однако редактор Python IDLE перезапускается при выполнении программы. Я ищу в Интернете, чтобы решить эту проблему. Есть какие-нибудь идеи?

5. @Chan IDLE — не лучший вариант для использования библиотеки, которая имеет цикл событий как PyQt, поскольку она заблокирует цикл событий того же IDLE. Так что профессионально вы не должны использовать IDLE.