Асинхронный или многопоточный запуск проекта

У меня имеется следующий код, парсит данные. Затем я импортирую его в свой основной проект где используя эти данные создаю графический интерфейс, но ждать пока оно спарсит очень долго, подскажите пожалуйста как лучше всегда запустить код парсинга в моём проекте что бы пока пользователь не вошел в нужную вкладку эти данные парсились. Через 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("Парсинг ещё выполняется...")
→ Ссылка