def check_request_status_code(request, url) -> bool: """ Проверка кода ответа запроса. """ if request.status_code == 200: # если запрос был выполнен успешно то l_message(gfn(), 'Успешный запрос!', color=Nm.BColors.OKBLUE) return True elif request.status_code == 400: l_message(gfn(), f'BAD request {url} : {str(request.status_code)}', color=Nm.BColors.FAIL) return False elif 400 < request.status_code < 500: l_message(gfn(), f'Client Error {url} : {str(request.status_code)}', color=Nm.BColors.FAIL) return False elif 500 <= request.status_code < 600: l_message(gfn(), f'Server Error {url} : {str(request.status_code)}', color=Nm.BColors.FAIL) return False else: l_message( gfn(), f'Неудачный запрос! Ответ {str(request.status_code)} : {str(request.status_code)}', color=Nm.BColors.FAIL) return False
def check_proxies(proxies_list: list): """ Проверяем список прокси :return: valid_proxies_list: возвращает список проверенных прокси: list :param proxies_list: лист с прокси для проверки : list """ l_message(gfn(), f'proxies_list {str(proxies_list)}', color=Nm.BColors.OKBLUE) mgr = multiprocessing.Manager() valid_proxies_list: list = mgr.list() n_chunks: int = 4 chunks = [proxies_list[i::n_chunks] for i in range(n_chunks)] parcs_list: list = [] for chunk in chunks: chunk_p = multiprocessing.Process(target=check_proxy, args=(chunk, valid_proxies_list)) parcs_list.append(chunk_p) chunk_p.start() for chunk_p in parcs_list: chunk_p.join() l_message(gfn(), f'valid_proxies_list {str(valid_proxies_list)}', color=Nm.BColors.OKBLUE) return valid_proxies_list
def _write_to_sheet(self): """Запись данных на лист.""" l_message(gfn(), 'Начало записи данных в файл', color=Nm.BColors.OKBLUE) doc_row: int = 1 for divs_iter in self.divs_requests: # записываем данные if doc_row == 1: self.wbook.Worksheets.Item(1).Cells( doc_row, 1).Value = divs_iter['rowNom'] else: self.wbook.Worksheets.Item(1).Cells(doc_row, 1).Value = doc_row - 1 self.wbook.Worksheets.Item(1).Cells(doc_row, 2).Value = divs_iter['ques'] self.wbook.Worksheets.Item(1).Cells( doc_row, 3).Value = divs_iter['company_title'] self.wbook.Worksheets.Item(1).Cells( doc_row, 4).Value = divs_iter['company_cid'] self.wbook.Worksheets.Item(1).Cells( doc_row, 5).Value = divs_iter['company_link_1'] self.wbook.Worksheets.Item(1).Cells( doc_row, 6).Value = divs_iter['company_sitelinks'] self.wbook.Worksheets.Item(1).Cells( doc_row, 7).Value = divs_iter['company_text'] self.wbook.Worksheets.Item(1).Cells( doc_row, 8).Value = divs_iter['company_contact'] doc_row += 1 l_message(gfn(), 'Данные записаны', color=Nm.BColors.OKBLUE)
def check_folder(*, path: str) -> bool: """ Проверка файл или каталог. """ if not os.path.exists(path): l_message(gfn(), 'Файл не найден', color=BColors.OKBLUE) return False return True
def start_work(self): """ функция парсера. """ assert self.urls is not None, str(gfn()) + 'urls not passed' for number, item_url in enumerate(self.urls): l_message(gfn(), f"\nЗапрос номер: {number + 1} \n", color=Nm.BColors.OKBLUE) try: self.url = item_url['url'] self.ques = item_url['ques'] if number <= 100: self.get_response() else: self.proxyes = self.get_proxy_pool_from_file() self.get_response_with_proxy() self.soup_request() # обработка ответа сервера if self.divs is not None: self.divs_text_shelves() self.result.extend(list(self.divs_requests)) self._time_rand(2, 4) except ConnectionError as err: l_message(gfn(), f" ConnectionError: {repr(err)}", color=Nm.BColors.FAIL) continue self.write_data_to_file()
def get_proxies(limit: int = 10): """ Собираем прокси с помощью proxybroker :return: proxies_list_get : список найденных прокси: list :param limit: лимит на колличество найденных прокси: int """ loop = asyncio.get_event_loop() proxies = asyncio.Queue() broker = Broker(proxies, timeout=12, max_conn=200, max_tries=2, verify_ssl=False, loop=loop) tasks = asyncio.gather(broker.grab(countries=['RU'], limit=limit), save_proxies(proxies, filename=PROXIES)) loop = asyncio.get_event_loop() loop.run_until_complete(tasks) # записываем собранное в proxies_list_get with open(PROXIES, 'r') as prx_row: proxies_list_get = prx_row.read().split('\n') l_message(gfn(), f'proxies_list_get {str(proxies_list_get)}', color=Nm.BColors.OKBLUE) return proxies_list_get
def check_ip(): """Check my public IP via tor. """ l_message( gfn(), f'My public IP {requests.get("http://www.icanha4zip.com").text[:-2]}', color=BColors.OKBLUE)
def _measure_time_request(function: str, t_start): """ Исмерение времени выполнения запросаю """ micro_seconds = (time.monotonic() - t_start) * 1000 l_message( function, f'Время request: {micro_seconds:2.2f} ms или {str(float(round(micro_seconds / 1000, 2)))} сек.', color=BColors.OKGREEN)
def time_rand(t_start: int = 1, t_stop: int = 30): """ Функция задержки выполнения кода на рандомный промежуток. """ time_random = random.randint(t_start, t_stop) l_message( gfn(), f'Время ожидания нового запроса time_rand {str(time_random)} sec', color=Nm.BColors.OKBLUE) for _ in range(time_random): time.sleep(random.uniform(0.8, 1.2))
def main(): """ Основная функция """ l_message(gfn(), '\n**** Start ****\n', color=Nm.BColors.OKBLUE) for _ in range(10): proxies_list_get = get_proxies(limit=gs.max_proxies) get_proxy = check_proxies(proxies_list_get) app_load_proxies_list(get_proxy) time_rand(10, 15) l_message(gfn(), '\n**** Done ****\n', color=Nm.BColors.OKBLUE)
def main(): """Основная функция с параметрами. """ l_message(gfn(), '\n**** Start ****\n', color=Nm.BColors.OKBLUE) urls = url_constructor_yandex(gs.queries_path, gs.base_url_yandex, gs.region_yandex, gs.within_time, gs.num_doc, gs.url_max_pos_yandex) parser = ParserYandex(urls=urls) parser.start_work() l_message(gfn(), '\n**** Done ****\n', color=Nm.BColors.OKBLUE)
async def save_proxies(proxies, filename: str): """ Сохраняем прокси от Broker в файл PROXIES :param proxies: найденный Broker прокси: object :param filename: полный путь к файлу для записи и хранения прокси: str """ l_message(gfn(), f'proxyes {proxies}', color=Nm.BColors.OKBLUE) with open(filename, 'w') as file: while True: proxy = await proxies.get() if proxy is None: break proto = 'https' if 'HTTPS' in proxy.types else 'http' row = f'{proto}://{proxy.host}:{proxy.port}\n' file.write(row)
def soup_request(self): """ Обработка ответа с помощью BeautifulSoup. Если есть нужные данные - передаёт на поиск нужных данных в divs_text_shelves. """ if not hasattr(self.request, self.soup_attribute): l_message(gfn(), 'Ответ не содержит текст :(', color=BColors.FAIL) return if self.request.text == '': l_message(gfn(), 'Ответ не содержит текстовых данных :(', color=BColors.FAIL) return soup = BeautifulSoup(self.request.text, 'lxml') # ответ self.divs = soup.find_all(class_=self.soup_class) # данные ответа if self.divs is None or len(self.divs) == 0: l_message(gfn(), 'Ответ не содержит нужных данных :(', color=BColors.FAIL) return l_message(gfn(), f'Всего найдено блоков {str(len(self.divs))}', color=BColors.OKBLUE)
def get_my_company_cid(i_row=None): """Найти и вернуть порядковый номер компании.""" try: my_company_cid: str = str(i_row - 1) l_message(gfn(), f'company_cid {my_company_cid}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_cid: str = '' return my_company_cid
def get_my_company_cid(div): """Найти и вернуть порядковый номер компании на странице. """ try: my_company_cid: str = str(div.get('data-cid')) l_message(gfn(), f'company_cid {my_company_cid}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_cid: str = '' return my_company_cid
def get_my_company_contact(div=None): """Найти и вернуть контакты компании.""" try: my_company_contact: str = 'N\A' l_message(gfn(), f'company_contact {my_company_contact}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_contact: str = 'N\A' return my_company_contact
def get_my_company_site_links(div): """Найти и вернуть ссылку на сайт компании.""" try: get_my_company_site_link: str = div.find( 'cite', attrs={'class': 'iUh30 bc tjvcx'}) l_message(gfn(), f'company_site_links {get_my_company_site_link}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) get_my_company_site_link: str = 'N\A' return get_my_company_site_link
def get_my_company_title(div): """Найти и вернуть название компании.""" try: my_company_title: str = div.text.replace( 'Почему мне показано это объявление?', '') l_message(gfn(), f'company_title {my_company_title}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_title: str = 'N\A' return my_company_title
def get_my_company_text(div): """Найти и вернуть описание компании.""" try: my_company_text: str = div.find('div', attrs={ 'class': 'MUxGbd yDYNvb lyLwlc' }).text.strip() l_message(gfn(), f'company_text {my_company_text}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_text: str = '' return my_company_text
def create_workbook(self): """ Создание обектов приложения Excel и обьекта страницы.""" try: self.excel_app = win32com.client.gencache.EnsureDispatch( 'Excel.Application') self.excel_app_start() if os.path.exists(self.full_path_to_file ): # файл excel существует то удаляем os.remove(self.full_path_to_file) self.wbook = self.excel_app.Workbooks.Add() self.wbook.SaveAs(self.full_path_to_file) l_message(gfn(), f'Книга создана в {self.full_path_to_file}', color=Nm.BColors.OKBLUE) self.wbook = self.excel_app.Workbooks.Open(self.full_path_to_file) except com_error as err: l_message(gfn(), f" pywintypes.com_error: {repr(err)}", color=Nm.BColors.FAIL) except TypeError as err: l_message(gfn(), f" TypeError: {repr(err)}", color=Nm.BColors.FAIL) try: self.wbook.Close(False) # save the workbook self.excel_app_quit() l_message(gfn(), "**** Аварийное завершение программы ****", color=Nm.BColors.FAIL) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) quit() return self.excel_app, self.wbook
def get_my_company_sitelinks(div): """Найти и вернуть ссылку на сайт компании. """ try: my_company_sitelinks: str = div.find( 'div', attrs={ 'class': 'sitelinks sitelinks_size_m organic__sitelinks' }).text.strip() l_message(gfn(), f'company_site_links {my_company_sitelinks}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_sitelinks: str = 'N/A' return my_company_sitelinks
def get_my_company_title(div): """Найти и вернуть название компании. """ try: my_company_title: str = div.find( 'h2', attrs={ 'class': "organic__title-wrapper typo typo_text_l typo_line_m" }).text.strip() l_message(gfn(), f'company_title {my_company_title}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_title: str = 'N/A' return my_company_title
def url_constructor_yandex(queries_path, selected_base_url, selected_region, within_time, num_doc=10, max_pos=3): """ Формирование запросов из запчастей. """ urls = [] # открываем файл с ключами по пути queries_path и считываем ключи with open(queries_path, 'r', encoding='utf-8') as file: query = [x.strip() for x in file] for ques in query: # перебираем ключи и формируем url на их основе divs_ques: str = ques if num_doc == 10: mod_url = selected_base_url + ques.replace( ' ', '%20') + '&lr=' + str(selected_region) + '&within=' + str( within_time) + '&lang=ru' else: mod_url = selected_base_url + ques.replace( ' ', '%20') + '&lr=' + str(selected_region) + '&within=' + str( within_time) + '&lang=ru' + '&num_doc=' + str(num_doc) for i in range( max_pos): # дополняем url и формируем для кажного запроса if i == 0: l_message(gfn(), mod_url, color=Nm.BColors.OKBLUE) urls.append({ 'url': mod_url, 'ques': divs_ques }) # перывя ссылка с ключем else: url = str(mod_url + '&p=' + str(i)) if url not in urls: l_message(gfn(), url, color=Nm.BColors.OKBLUE) urls.append({ 'url': url, 'ques': divs_ques }) # остальные ссылки с ключом return urls
def get_my_company_link_1(div): """Найти и вернуть быструю ссылку на сайт компании.""" try: my_company_link_1: str = div.find('span', attrs={ 'class': 'gBIQub KETUZd qzEoUe' }).text x: int = my_company_link_1.index('/') my_company_link_1 = my_company_link_1[0:x] l_message(gfn(), f'company_link_1 {my_company_link_1}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_link_1: str = '' return my_company_link_1
def get_my_company_text(div): """Найти и вернуть описание компании. """ try: my_company_text: str = div.find( 'div', attrs={ 'class': 'text-container typo typo_text_m typo_line_m organic__text' }).text.strip() l_message(gfn(), f'company_text {my_company_text}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_text: str = '' return my_company_text
def file_writer(self): """Записываем данные в файл Excel.""" if len(self.divs_requests) == 0: l_message(gfn(), '\n Нет данных для записи в файл! \n', color=Nm.BColors.FAIL) return self.insert_headers_divs_requests() excel_app, wbook = self.create_workbook() if __debug__ and not PASSED: assert excel_app is not None, 'Не удалось подключится к excel' assert wbook is not None, 'Не удалось создать книгу' try: self._write_to_sheet() wbook.Close( True, self.full_path_to_file) # сохраняем изменения и закрываем self.excel_app_quit() except Exception as err: l_message(gfn(), f" Exception: {repr(err)}", color=Nm.BColors.FAIL) l_message(gfn(), 'Не удалось записать данные', color=Nm.BColors.FAIL) self.excel_app_quit() return
def get_my_company_link_1(div): """Найти и вернуть быструю ссылку на сайт компании. """ try: my_company_link_1: str = div.find( 'a', attrs={ 'class': 'link link_theme_outer path__item i-bem' }).text.strip() text: int = my_company_link_1.rfind('›') if text > 0: my_company_link_1 = my_company_link_1[0:text] l_message(gfn(), f'company_link_1 {my_company_link_1}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_link_1: str = '' return my_company_link_1
def get_my_company_contact(div): """Найти и вернуть контакты компании. """ try: my_company_contact: str = div.find('div', attrs={ 'class': 'serp-meta__item' }).text.strip() text: int = my_company_contact.rfind('+') if text > 0: my_company_contact = my_company_contact[text:] l_message(gfn(), f'company_contact {my_company_contact}', color=Nm.BColors.OKBLUE) except AttributeError as err: l_message(gfn(), f" AttributeError: {repr(err)}", color=Nm.BColors.FAIL) my_company_contact: str = 'N/A' return my_company_contact
def app_load_proxies_list(get_proxy: list): """ Добавляем проверенные прокси в proxies_list. :param get_proxy: добаляет список get_proxy в файл PROXIES_LIST: list """ try: # добавляем прокси к уже проверенным with open(PROXIES_LIST, 'r') as file: proxies_list: list = file.read().split('\n') except FileNotFoundError as err: l_message(gfn(), f"FileNotFoundError: {repr(err)}", color=Nm.BColors.FAIL) # если файл пустой - обнуляем список proxies_list = [] if proxies_list: get_proxy.extend(proxies_list) # преобразуев множество чтобы удалить повторы и обратно в list get_proxy = list(set(get_proxy)) l_message(gfn(), f"{str(get_proxy)}", color=Nm.BColors.OKBLUE) with open(PROXIES_LIST, 'w') as file: file.write('\n'.join(get_proxy))
def get_response(self): """ Функция посылает запрос и получает ответ. Если ответ есть - передаёт на обработку. """ for header in self.headers: try: self.session = self.get_session() self.request: Response = self.session.get( self.url, headers=header, stream=True, timeout=self.request_timeout) if self.check_request_status_code(self.request): l_message(gfn(), 'Успешный запрос!', color=BColors.OKBLUE) self.close_session() return self.request else: l_message( gfn(), 'Ошибка при установке соединения! проверьте HEADERS!', color=BColors.FAIL) continue except Exception as err: l_message(gfn(), f"Exception: {repr(err)}", color=BColors.FAIL)