Всем привет!
Может быть кто-то сталкивался с проблемой. Стоит последний Python и последняя версия библиотеки Beautiful soup.
Хочу в потоке начать парсить страницы. Поток без Beautiful soup работает на ура. Но как только я подставляю функционал парсинга выскакивает ошибка
QThread: Destroyed while thread is still running
Самое интересное это то, что при запуске я прохожу две итерации в цикле, а дальше вылетает с ошибкой
Класс создания потока
class ParserController:
def __init__(self, model, view):
self._model = model
self._view = view
def query_add(self, data):
if self._model.insert_data(data):
print('Запись добавлена в базу')
else:
print('Запись НЕ добавлена в базу')
def start_parse_autovia(self):
self.thread_1 = QtCore.QThread()
self.autovia_thread = ParseAutovia()
self.autovia_thread.moveToThread(self.thread_1)
self.thread_1.started.connect(self.autovia_thread.run)
self.autovia_thread.query.connect(self.query_add)
self.autovia_thread.finished.connect(self.thread_1.quit)
self.thread_1.start()
Класс самого парсера
class ParseAutovia(QtCore.QObject):
finished = QtCore.pyqtSignal()
query = QtCore.pyqtSignal(dict)
START_PAGE = 'https://www.autovia.sk/osobne-auta'
PAGINATION_PAGE = 'https://www.autovia.sk/osobne-auta/?p[page]='
def get_data(self, html):
# Get title
try:
title = html.find('h1').text.strip()
except:
title = ''
# Get phone
try:
phone = html.find('div', class_='resp-buttons').find_all('a')[0]['href']
except:
phone = ''
# Get name
try:
name = html.find('div', class_='resp-contact-top').find('span', class_='resp-subject').text.strip()
except:
name = ''
# Get location
try:
location = html.find('div', class_='resp-contact-bottom').find('div', class_='resp-location').find('span').text.strip()
except:
location = ''
# Get date
try:
date = html.find('div', class_='resp-meta').find_all('div', class_='col-6')[0].text.strip()
date = date.replace('Aktualizované: ', '')
except:
date = ''
# Get login
try: # Логин продавца
login = html.find('div', class_='resp-contact-top').find('a', class_='resp-subject').text.strip()
except:
login = ''
# Get login link
try:
login_link = html.find('div', class_='resp-contact-top').find('a', class_='resp-subject')['href']
except:
login_link = ''
# Get page link
try:
page_link = html.find('meta', attrs={'property': 'og:url'})['content']
except:
page_link = ''
data = {
'title': title,
'phone': phone,
'name': name,
'location': location,
'date': date,
'login': login,
'login_link': login_link,
'page_link': page_link
}
return data
def get_html(self, url):
r = requests.get(url)
soup = BeautifulSoup(r.text, 'lxml')
return soup
def get_pagination_count(self):
soup = self.get_html(self.START_PAGE)
count = soup.find('div', class_='resp-pager').find('label', class_='resp-after').text.strip()
count = int(count.replace('z', '').replace(' ', ''))
return count
def get_pagination_links(self, pagination):
url = self.PAGINATION_PAGE + str(pagination)
soup = self.get_html(url)
links = []
items = soup.find('section', class_='resp-search-results').find_all('div', class_='resp-item')
for item in items:
link = item.find('h2').find('a').get('href')
links.append(link)
return links
def run(self):
pagination_count = self.get_pagination_count()
pagination = 1
while pagination <= pagination_count:
pagination_links = self.get_pagination_links(pagination)
for url in pagination_links:
html = self.get_html(url)
data = self.get_data(html)
self.query.emit(data)
print(data['phone'])
pagination += 1
self.finished.emit()
Если запустить это в потоке - без проблем отработает
def run(self):
for i in range(100):
print(i)
i += 1
time.sleep(2)
Прилагаю точку входа в программу
import sys
from PyQt5 import QtWidgets
from model.ParserModel import ParserModel
from controller.ParserController import ParserController
class AppParser(QtWidgets.QApplication):
def __init__(self, sys_args):
super(AppParser, self).__init__(sys_args)
self._model = ParserModel()
self._controller = ParserController(self._model)
def main():
app = AppParser(sys.argv)
sys.exit(app.exec())
if __name__ == '__main__':
main()