Асинхронный или многопоточный запуск проекта
У меня имеется следующий код, парсит данные. Затем я импортирую его в свой основной проект где используя эти данные создаю графический интерфейс, но ждать пока оно спарсит очень долго, подскажите пожалуйста как лучше всегда запустить код парсинга в моём проекте что бы пока пользователь не вошел в нужную вкладку эти данные парсились. Через threading
хочу но не знаю как запустить в многопоточном что бы затем мне выдало значение через return
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
header = {'user-agent': UserAgent().random}
url = 'https://randevu05.ru/'
def data_category():
name_cat = []
link_cat = []
img_cat = []
r = requests.get(url, headers = header)
print('данные получены')
r.encoding = 'UTF-8'
soup = BeautifulSoup(r.text, 'lxml')
block = soup.find('section', class_='menu-cart')
block = block.find_all('a')
for i in range(len(block)):
name_cat.append(block[i].find('h4', class_='menu-cart__h4').text)
link_cat.append(f"{url}{block[i].get('href')}")
img_cat.append(f"{url}{block[i].find('img', class_='menu-cart__img').get('src')}")
print(i)
return {'name': name_cat, 'link': link_cat, 'img': img_cat}
def data_product(url):
req = requests.get(url, headers = header)
req.encoding = 'UTF-8'
soup = BeautifulSoup(req.text, 'lxml')
block = soup.find('ul', class_='card')
namee = block.find_all('h3', class_='card__title')#.text
descc = block.find_all('p', class_='card__desc')#.text
pricee = block.find_all('p', class_='card__price')#.text
name = []
desc = []
price = []
for n, d, p in zip(namee, descc, pricee):
name.append(n.text)
desc.append(d.text)
price.append(p.text)
return {'name': name, 'desc': desc, 'price': price}
names = []
descs = []
prices = []
count_all_data = 0
url_all_data = data_category()['link']
for i in url_all_data:
names.append(data_product(i)['name'])
descs.append(data_product(i)['desc'])
prices.append(data_product(i)['price'])
count_all_data+=1
print(len(url_all_data) - count_all_data)
Ответы (1 шт):
Автор решения: Рустам Рысаев
→ Ссылка
Для того чтобы парсинг данных выполнялся в фоновом потоке, используйте библиотеку threading
import threading
import queue
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
header = {'user-agent': UserAgent().random}
url = 'https://randevu05.ru/'
# Функция для парсинга категорий
def data_category():
name_cat = []
link_cat = []
img_cat = []
r = requests.get(url, headers=header)
print('Данные категорий получены')
r.encoding = 'UTF-8'
soup = BeautifulSoup(r.text, 'lxml')
block = soup.find('section', class_='menu-cart')
block = block.find_all('a')
for i in range(len(block)):
name_cat.append(block[i].find('h4', class_='menu-cart__h4').text)
link_cat.append(f"{url}{block[i].get('href')}")
img_cat.append(f"{url}{block[i].find('img', class_='menu-cart__img').get('src')}")
print(i)
return {'name': name_cat, 'link': link_cat, 'img': img_cat}
# Функция для парсинга продуктов
def data_product(url):
req = requests.get(url, headers=header)
req.encoding = 'UTF-8'
soup = BeautifulSoup(req.text, 'lxml')
block = soup.find('ul', class_='card')
namee = block.find_all('h3', class_='card__title')
descc = block.find_all('p', class_='card__desc')
pricee = block.find_all('p', class_='card__price')
name = []
desc = []
price = []
for n, d, p in zip(namee, descc, pricee):
name.append(n.text)
desc.append(d.text)
price.append(p.text)
return {'name': name, 'desc': desc, 'price': price}
# Функция для выполнения парсинга в отдельном потоке
def parse_data_in_thread(result_queue):
try:
# Получаем ссылки на категории
categories = data_category()
url_all_data = categories['link']
names, descs, prices = [], [], []
count_all_data = 0
# Парсим продукты для каждой категории
for i in url_all_data:
product_data = data_product(i)
names.append(product_data['name'])
descs.append(product_data['desc'])
prices.append(product_data['price'])
count_all_data += 1
print(f"Прогресс: {count_all_data}/{len(url_all_data)}")
# Возвращаем данные через очередь
result_queue.put({
'categories': categories,
'products': {'name': names, 'desc': descs, 'price': prices}
})
except Exception as e:
result_queue.put({'error': str(e)})
# Инициализация очереди и потока
result_queue = queue.Queue()
parsing_thread = threading.Thread(target=parse_data_in_thread, args=(result_queue,))
parsing_thread.start()
# В основном проекте вы можете проверять, завершён ли парсинг:
def check_parsing_status():
if not parsing_thread.is_alive(): # Поток завершён
result = result_queue.get()
if 'error' in result:
print(f"Ошибка парсинга: {result['error']}")
else:
print("Данные успешно спарсены!")
print(result) # Здесь можно обработать данные
else:
print("Парсинг ещё выполняется...")