<reponame>Pendosv/AutoParser<gh_stars>0
import json
from abc import ABC, abstractmethod
from random import choice
from typing import Optional, Union

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait as Wait

from src.utils import get_data_list


class WrongEMailError(Exception):
    pass


class Bot(ABC):
    _result = None

    def __init__(self, *, useragent: str = None, proxy: Optional[Union[list[str, int], tuple[str, int]]] = None):
        self.USERAGENT = useragent
        self.PROXY = proxy

        self._urls = self.__get_urls_json()
        options = Options()
        profile = webdriver.FirefoxProfile()

        # True - не показывать окно браузера
        options.headless = False

        # установка useragent
        if self.USERAGENT is not None:
            profile.set_preference("general.useragent.override", self.USERAGENT)

        # установка прокси
        if self.PROXY is not None:
            host, port = self.PROXY
            profile.set_preference("network.proxy.type", 1)
            profile.set_preference("network.proxy.http", host)
            profile.set_preference("network.proxy.http_port", port)
            profile.set_preference("network.proxy.https", host)
            profile.set_preference("network.proxy.https_port", port)
            profile.set_preference("network.proxy.ssl", host)
            profile.set_preference("network.proxy.ssl_port", port)
            profile.set_preference("network.proxy.ftp", host)
            profile.set_preference("network.proxy.ftp_port", port)
            profile.set_preference("network.proxy.socks", host)
            profile.set_preference("network.proxy.socks_port", port)

        profile.update_preferences()
        self._driver = webdriver.Firefox(firefox_profile=profile, firefox_options=options)

    @staticmethod
    def get_random_useragent():
        return choice(get_data_list('src/data/User-Agent.txt', size=8192))

    @staticmethod
    def __get_urls_json():
        return json.load(open('src/data/urls.json'))

    @staticmethod
    def _get_standard_number(number: str) -> str:
        return number.replace(' ', '').replace('-', '')

    @abstractmethod
    def get_result(self):
        pass

    def check_useragent_ip(self):
        self._driver.get('http://whatsmyuseragent.org')
        ua = self._driver.find_element_by_xpath('//div[@class="user-agent"]').text
        ip = self._driver.find_element_by_xpath('//div[@class="ip-address"]').text.split(':')[1].strip()
        return ua, ip

    def __del__(self):
        self._driver.quit()


class MailBot(Bot):

    def __init__(self, target_email: str, **kwargs):
        self.__target_email = target_email
        super().__init__(**kwargs)

    def get_result(self) -> list:
        res = [self.__get_phone_number()]
        return res

    def __get_phone_number(self):
        self._driver.get(self._urls['mail'].format(self.__target_email))

        # Ожидает пока загрузится кнопка
        Wait(self._driver, 3).until(

            # ищет кнопку "Другие способы" и нажимает на неё
            ec.presence_of_element_located((By.XPATH, '//span[@data-test-id="more-link"]'))) \
            .find_element_by_class_name('base-0-2-69').click()

        # номер
        phone_number = self._driver.find_element_by_xpath('//span[@data-test-id="phone-link"]')
        return phone_number.get_attribute('data-item')


class AutoRuParser(Bot):
    _result = []

    def __init__(self, model: str, **kwargs):
        self.__model = model
        super().__init__(**kwargs)

    def get_result(self) -> list:
        res = []

        for i in self.__get_urls_by_model():
            try:
                res.append(self.__get_phone(i))
            except TimeoutException as e:
                print(repr(e))
                continue

        return res

    def __get_urls_by_model(self) -> list:

        self._driver.get(self._urls['autoru'].format(self.__model))

        links = self._driver.find_elements_by_xpath('//a[@class="Link ListingItemTitle-module__link"]')[1:10]

        res = []
        for i in links:
            res.append(i.get_attribute('href'))
        return res

    def __get_phone(self, url: str) -> tuple:
        self._driver.get(url)

        try:
            model = self._driver.find_element_by_xpath('//h1[@class="vvPW6PJaQXQwmDJz3qWOG__title"]').text.strip()
        except NoSuchElementException:
            model = '[NF]'

        try:
            price = self._driver.find_element_by_xpath('//span[@class="OfferPriceCaption__price"]').text.strip()
        except NoSuchElementException:
            price = '[NF]'

        Wait(self._driver, 3).until(

            # ищет кнопку "Показать номер" и нажимает на нее
            ec.presence_of_element_located((By.XPATH,
                                            '//button[@class="Button Button_color_green Button_size_l '
                                            'Button_type_button Button_width_full Button_radius_r4 '
                                            'OfferPhone-module__phone CardOwner-module__phone '
                                            'OfferPhone-module__phoneButton"]'))).click()

        try:
            number = self._driver.find_element_by_xpath('//div[@class="OfferPhone-module__phone-title"]').text
            number = self._get_standard_number(number)
        except NoSuchElementException:
            number = '[NF]'
        return model, price, number

import json
from abc import ABC, abstractmethod
from random import choice
from typing import Optional, Union

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait as Wait

from src.utils import get_data_list


class WrongEMailError(Exception):
    pass


class Bot(ABC):
    _result = None

    def __init__(self, *, useragent: str = None, proxy: Optional[Union[list[str, int], tuple[str, int]]] = None):
        self.USERAGENT = useragent
        self.PROXY = proxy

        self._urls = self.__get_urls_json()
        options = Options()
        profile = webdriver.FirefoxProfile()

        # True - не показывать окно браузера
        options.headless = False

        # установка useragent
        if self.USERAGENT is not None:
            profile.set_preference("general.useragent.override", self.USERAGENT)

        # установка прокси
        if self.PROXY is not None:
            host, port = self.PROXY
            profile.set_preference("network.proxy.type", 1)
            profile.set_preference("network.proxy.http", host)
            profile.set_preference("network.proxy.http_port", port)
            profile.set_preference("network.proxy.https", host)
            profile.set_preference("network.proxy.https_port", port)
            profile.set_preference("network.proxy.ssl", host)
            profile.set_preference("network.proxy.ssl_port", port)
            profile.set_preference("network.proxy.ftp", host)
            profile.set_preference("network.proxy.ftp_port", port)
            profile.set_preference("network.proxy.socks", host)
            profile.set_preference("network.proxy.socks_port", port)

        profile.update_preferences()
        self._driver = webdriver.Firefox(firefox_profile=profile, firefox_options=options)

    @staticmethod
    def get_random_useragent():
        return choice(get_data_list('src/data/User-Agent.txt', size=8192))

    @staticmethod
    def __get_urls_json():
        return json.load(open('src/data/urls.json'))

    @staticmethod
    def _get_standard_number(number: str) -> str:
        return number.replace(' ', '').replace('-', '')

    @abstractmethod
    def get_result(self):
        pass

    def check_useragent_ip(self):
        self._driver.get('http://whatsmyuseragent.org')
        ua = self._driver.find_element_by_xpath('//div[@class="user-agent"]').text
        ip = self._driver.find_element_by_xpath('//div[@class="ip-address"]').text.split(':')[1].strip()
        return ua, ip

    def __del__(self):
        self._driver.quit()


class MailBot(Bot):

    def __init__(self, target_email: str, **kwargs):
        self.__target_email = target_email
        super().__init__(**kwargs)

    def get_result(self) -> list:
        res = [self.__get_phone_number()]
        return res

    def __get_phone_number(self):
        self._driver.get(self._urls['mail'].format(self.__target_email))

        # Ожидает пока загрузится кнопка
        Wait(self._driver, 3).until(

            # ищет кнопку "Другие способы" и нажимает на неё
            ec.presence_of_element_located((By.XPATH, '//span[@data-test-id="more-link"]'))) \
            .find_element_by_class_name('base-0-2-69').click()

        # номер
        phone_number = self._driver.find_element_by_xpath('//span[@data-test-id="phone-link"]')
        return phone_number.get_attribute('data-item')


class AutoRuParser(Bot):
    _result = []

    def __init__(self, model: str, **kwargs):
        self.__model = model
        super().__init__(**kwargs)

    def get_result(self) -> list:
        res = []

        for i in self.__get_urls_by_model():
            try:
                res.append(self.__get_phone(i))
            except TimeoutException as e:
                print(repr(e))
                continue

        return res

    def __get_urls_by_model(self) -> list:

        self._driver.get(self._urls['autoru'].format(self.__model))

        links = self._driver.find_elements_by_xpath('//a[@class="Link ListingItemTitle-module__link"]')[1:10]

        res = []
        for i in links:
            res.append(i.get_attribute('href'))
        return res

    def __get_phone(self, url: str) -> tuple:
        self._driver.get(url)

        try:
            model = self._driver.find_element_by_xpath('//h1[@class="vvPW6PJaQXQwmDJz3qWOG__title"]').text.strip()
        except NoSuchElementException:
            model = '[NF]'

        try:
            price = self._driver.find_element_by_xpath('//span[@class="OfferPriceCaption__price"]').text.strip()
        except NoSuchElementException:
            price = '[NF]'

        Wait(self._driver, 3).until(

            # ищет кнопку "Показать номер" и нажимает на нее
            ec.presence_of_element_located((By.XPATH,
                                            '//button[@class="Button Button_color_green Button_size_l '
                                            'Button_type_button Button_width_full Button_radius_r4 '
                                            'OfferPhone-module__phone CardOwner-module__phone '
                                            'OfferPhone-module__phoneButton"]'))).click()

        try:
            number = self._driver.find_element_by_xpath('//div[@class="OfferPhone-module__phone-title"]').text
            number = self._get_standard_number(number)
        except NoSuchElementException:
            number = '[NF]'
        return model, price, number
# True - не показывать окно браузера # установка useragent # установка прокси # Ожидает пока загрузится кнопка # ищет кнопку "Другие способы" и нажимает на неё # номер # ищет кнопку "Показать номер" и нажимает на нее