import asyncio
import time
from random import randint
from bs4 import BeautifulSoup
from playwright.async_api import async_playwright
from fake_useragent import UserAgent
import requests

# Set up Fake UserAgent for random user-agents
ua = UserAgent()

# Function to implement random delay (rate limiting)
def random_delay(minimum=2, maximum=10):
    sleep_time = randint(minimum, maximum)
    time.sleep(sleep_time)

# Function to check if a website’s robots.txt allows scraping to implement point 3
def can_scrape(url):
    response = requests.get(url + "/robots.txt")
    if "Disallow: /" in response.text:
        return False
    return True

async def get_token_info(token_symbol, proxy):
    # Check if we can scrape the requested URL
    url = "https://moonarch.app/"

    if not can_scrape(url):
        print("Scraping is not allowed according to the website’s robots.txt.")
        return None

    async with async_playwright() as p:
        browser = await p.chromium.launch(
            headless=True,
            proxy={"server": proxy},
            user_agent=ua.random,
        )

        context = await browser.new_context()

        try:
            page = await context.new_page()
            await page.goto(url)

            search_box_selector = 'input.form-control'
            await page.wait_for_selector(search_box_selector)

            search_box = await page.query_selector(search_box_selector)
            await search_box.type(token_symbol)

            await page.wait_for_selector('.token-info')
            await page.wait_for_selector('.infocard')

            soup = BeautifulSoup(await page.content(), "html.parser")
            token_info_element = soup.find("div", class_="token-info")
            infocard_element = soup.find("div", class_="infocard")

            check_alert_element = soup.find("div", class_="token-check-message check-alert")
            check_warning_element = soup.find("div", class_="token-check-message check-warning")
            check_info_element = soup.find("div", class_="token-check-message check-info")
            not_verified_element = soup.find("div", class_="not-verified")

            check_alert_status = "Yes" if check_alert_element else "None"
            check_warning_status = "Yes" if check_warning_element else "None"
            check_info_status = "Yes" if check_info_element else "None"
            not_verified_status = "Yes" if not_verified_element else "None"

            if token_info_element and infocard_element:
                token_name_element = token_info_element.find("span", class_="name")
                token_symbol_element = token_info_element.find("span", class_="symbol")
                info_items = infocard_element.find_all("li")

                if token_name_element and token_symbol_element and len(info_items) >= 7:
                    token_name = token_name_element.text.strip()
                    token_symbol = token_symbol_element.text.strip()
                    price = info_items[0].find("span", class_="value").text.strip()
                    max_supply = info_items[1].find("span", class_="value").text.strip()
                    market_cap = info_items[2].find("span", class_="value").text.strip()
                    liquidity = info_items[3].find("span", class_="value").text.strip()
                    liq_mc = info_items[4].find("span", class_="value").text.strip()
                    token_age = info_items[6].find("span", class_="value").text.strip()

                    await browser.close()

                    # Implement rate limiting (point 1)
                    random_delay()

                    return {
                        "name": token_name,
                        "symbol": token_symbol,
                        "price": price,
                        "max_supply": max_supply,
                        "market_cap": market_cap,
                        "liquidity": liquidity,
                        "liq_mc": liq_mc,
                        "token_age": token_age,
                        "check_alert": check_alert_status,
                        "check_warning": check_warning_status,
                        "check_info": check_info_status,
                        "not_verified": not_verified_status
                    }

                else:
                    await browser.close()
                    error_info = f"token_name_element: {token_name_element}, token_symbol_element: {token_symbol_element}, info_items count: {len(info_items)}"
                    return {"error": f"Failed to find the required info items or name and.symbol. Error_info: {error_info}"}

            else:
                await browser.close()
                return {"error": f"Failed to find the required elements for token_info_element ({token_info_element}) and infocard_element ({infocard_element})."}

        except Exception as ex:
            print(f"Error occurred while scraping: {ex}")
            await browser.close()
            return None

token_symbols = [
"0x0E481Fa712201f61dAf97017138Efaa69e2A3df3",
"0x2023aa62A7570fFd59F13fdE2Cac0527D45abF91",
"0x2222222222222222222222222222222222222222",
"0x0d4890ecEc59cd55D640d36f7acc6F7F512Fdb6e"
# Add more token symbols here…
]
async def main():
    proxy_url = "http://proxy.example.com:8080"
    while True:
        result_tasks = [get_token_info(token_symbol, proxy_url) for token_symbol in token_symbols]
        results = await asyncio.gather(*result_tasks)
        print(results)

        await asyncio.sleep(60)

asyncio.run(main())


The code above gives an error

C:\Users\AshotxXx\PycharmProjects\Parcing\pythonProject4\venv\Scripts\python.exe C:\Users\AshotxXx\PycharmProjects\Parcing\pythonProject4\main.py 
Traceback (most recent call last):
  File "C:\Users\AshotxXx\PycharmProjects\Parcing\pythonProject4\main.py", line 6, in <module>
    from fake_useragent import UserAgent
ModuleNotFoundError: No module named 'fake_useragent'

Process finished with exit code 1

Fix it