У меня есть скребок PyQt5, который должен визуализировать веб-страницу перед ее очисткой, так как веб-страница содержит динамические данные c. Это самая простая версия скрипта, которая, к сожалению, все еще состоит из нескольких частей.
Единственная причина, по которой рендеринг необходимо вызывать из функции, заключается в том, что иногда он зависает бесконечно, поэтому он имеет многопоточность тайм-аут на это. Это все хорошо, за исключением того, что Render не будет работать должным образом внутри функции, потому что QApplication по какой-то причине не передается должным образом. Я могу определить App = QApplication (sys.argv) и поместить класс Render в функцию ScrapeClockwise, но для этого необходимо также определить App внутри этой функции (по какой-то причине его нельзя передать). И затем, если функция по истечении этого времени он вылетит без закрытия QApplication, поэтому при следующем запуске функции программа просто вызовет sh. ЭТОТ ДАЖЕ ПРОИСХОДИТ, ЕСЛИ ЭТО ОПРЕДЕЛЕНО В ОТНОШЕНИИ ИСКЛЮЧИТЕЛЬНОЙ ЗАЯВКИ, что очень странно.
Как вы можете видеть, здесь много странных взаимодействий, и если бы кто-нибудь мог пролить свет на любую из них, я бы будь невероятно благодарным, я уже некоторое время бьюсь головой об этом.
import sys
from PyQt5.QtCore import *
from PyQt5.QtWebKitWidgets import *
from PyQt5.QtWidgets import *
from bs4 import BeautifulSoup
import threading
import functools
from threading import Thread
def timeout(timeout):
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
res = [Exception('function [%s] timeout [%s seconds] exceeded!' % (func.__name__, timeout))]
def newFunc():
try:
res[0] = func(*args, **kwargs)
except Exception as e:
res[0] = e
t = Thread(target=newFunc)
t.daemon = True
try:
t.start()
t.join(timeout)
except Exception as je:
print('error starting thread')
raise je
ret = res[0]
if isinstance(ret, BaseException):
raise ret
return ret
return wrapper
return deco
APP = QApplication(sys.argv)
class SomeClass(QWidget):
def some_method(self):
APP.processEvents(QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers |
QEventLoop.WaitForMoreEvents)
class Render(QWebPage):
def __init__(self, url):
QWebPage.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.mainFrame().load(QUrl(url))
APP.exec_()
def _loadFinished(self, result):
self.frame = self.mainFrame()
APP.quit()
def ScrapeClockwise(l):
url = "https://www.clockwisemd.com/hospitals/" + str(l).zfill(4) + "/appointments/new"
print(url)
r = Render(url)
result = r.frame.toHtml()
soup = BeautifulSoup(result, 'html.parser')
info = soup.find_all('h4')
for i in info:
print(i.get_text())
l = 0
while True:
func = timeout(5)(ScrapeClockwise)
try:
func(str(l))
except Exception as e:
print(e)
pass # handle errors here
l += 1