Перейти к содержимому

Как нажать на кнопку selenium python

  • автор:

Обрабатываем нажатие кнопки в Selenium

В материале «Парсим данные, используя Buetiful Soup и Selenium» мы уже рассмотрели, как быть, когда данные на странице динамически подгружаются при скролле страницы. Но бывают ситуации, когда новые данные можно получить, только нажав на кнопку «Показать ещё» — сегодня узнаем, как через Selenium сымитировать нажатие кнопки для полного открытия страницы, соберём идентификаторы пива, оценки к каждому продукту и отправим данные в Clickhouse

Структура страницы

Возьмём случайную пивоварню — у неё 105 чекинов, то есть, отзывов. Страница с чекинами пивоварни показывает не более 25 чекинов и выглядит так:

Если попробуем промотать в самый низ, столкнёмся с той самой кнопкой, мешающей нам взять все 105 за раз:

Мы поступим так: выясним, к какому классу относится элемент кнопки и будем на неё нажимать, пока это возможно. Так как Selenium запускает браузер, следующая кнопка «Показать ещё» может не успеть прогрузиться, поэтому между нажатиями поставим интервал в пару секунд. Как только страница раскроется полностью — мы возьмём её содержимое и распарсим нужные данные из чекинов. Зайдём в код страницы и найдём кнопку — она относится к классу more_checkins .

У кнопки есть свойства стиля, а именно — display . В случае, если кнопка должна отображаться, display принимает значение block . Но когда промотаем страницу до самого конца, кнопку не нужно будет показывать, ведь открывать больше нечего — поэтому display кнопки примет значение none . В случае, если мы запросим у кнопки display и вернётся none будем знать, что открывать больше нечего и можно перестать жать на кнопку.

Пишем код

Начнём с импорта библиотек:

import time from selenium import webdriver from bs4 import BeautifulSoup as bs import re from datetime import datetime from clickhouse_driver import Client

Chromedriver, необходимый для запуска браузера через Selenium, можно установить с официальной страницы

Подключимся к базе данных, зададим cookies:

client = Client(host='ec1-23-456-789-10.us-east-2.compute.amazonaws.com', user='', password='', port='9000', database='') count = 0 cookies = < 'domain':'untappd.com', 'expiry':1594072726, 'httpOnly':True, 'name':'untappd_user_v3_e', 'path':'/', 'secure':False, 'value':'your_value' >

О том, как запускать Selenium с cookies можно прочитать в материале «Парсим данные каталога сайта, используя Beautiful Soup и Selenium». Нам нужен параметр untappd_user_v3_e.

Так как мы планируем работать с пивоварнями, у которых более сотни тысяч чекинов, может оказаться так, что страница будет чересчур тяжёлой, и нагрузка на машину будет огромна. Чтобы этого избежать, отключим всё лишнее, а затем подключим cookie для авторизации:

options = webdriver.ChromeOptions() prefs = > options.add_experimental_option('prefs', prefs) options.add_argument("start-maximized") options.add_argument("disable-infobars") options.add_argument("--disable-extensions") driver = webdriver.Chrome(options=options) driver.get('https://untappd.com/TooSunnyBrewery') driver.add_cookie(cookies)

Напишем функцию, которая принимает ссылку, переходит по ней, полностью раскрывает страницу и возвращает нам soup, который можно будет распарсить. Получим display кнопки и запишем в переменную more_checkins : пока он не равен none будем нажимать на кнопку и снова получать её display . Сделаем интервал в две секунды между нажатиями, чтобы подождать прогрузку страницы. Как только будет получена вся страница, переведём её в soup библиотекой bs4 .

def get_html_page(url): driver.get(url) driver.maximize_window() more_checkins = driver.execute_script("var more_checkins=document.getElementsByClassName('more_checkins_logged')[0].style.display;return more_checkins;") print(more_checkins) while more_checkins != "none": driver.execute_script("document.getElementsByClassName('more_checkins_logged')[0].click()") time.sleep(2) more_checkins = driver.execute_script("var more_checkins=document.getElementsByClassName('more_checkins_logged')[0].style.display;return more_checkins;") print(more_checkins) source_data = driver.page_source soup = bs(source_data, 'lxml') return soup

Напишем следующую функцию: она тоже будет принимать url страницы, передавать его в get_html_page , получать soup и парсить его. Функция вернёт запакованные списки с идентификатором пива и оценкой к нему.

О том, как парсить элементы страницы мы уже говорили в материале «Парсим данные каталога сайта, используя Beautiful Soup».

def parse_html_page(url): soup = get_html_page(url) brewery_id = soup.find_all('a', )[0]['href'][28:] items = soup.find_all('div', ) checkin_rating_list = [] beer_id_list = [] count = 0 print('Заполняю списки') for checkin in items: print(count, '/', len(items)) try: checkin_rating_list.append(float(checkin.find('div', )['data-rating'])) except Exception: checkin_rating_list.append('cast(Null as Nullable(Float32))') try: beer_id_list.append(int(checkin.find('a', )['href'][-7:])) except Exception: beer_id_list.append('cast(Null as Nullable(UInt64))') count += 1 return zip(checkin_rating_list, beer_id_list)

Наконец, напишем вызов функций по пивоварням. В материале «Использование словарей в Clickhouse на примере данных Untappd» мы уже рассмотрели, как получить список идентификаторов российских пивоварен — обратимся к нему через таблицу в Clickhouse

brewery_list = client.execute('SELECT brewery_id FROM brewery_info')

Если посмотрим на brewery_list , то узнаем, что данные вернулись в неудобном формате: это список кортежей.

Небольшое лямбда-выражение позволит его «выпрямить»:

flatten = lambda lst: [item for sublist in lst for item in sublist] brewery_list = flatten(brewery_list)

Работать с таким списком значительно комфортнее:

Для каждой пивоварни в списке сформируем url — он состоит из стандартной ссылки и идентификатора пивоварни в конце. Отправим url в функцию parse_html_page , которая сама вызовет get_html_page и вернёт списки с beer_id и rating_score . Так как два списка вернутся упакованными можем пройти по ним итератором, сформировав кортеж и отправив его в Clickhouse.

for brewery_id in brewery_list: print('Беру пивоварню с id', brewery_id, count, '/', len(brewery_list)) url = 'https://untappd.com/brewery/' + str(brewery_id) returned_checkins = parse_html_page(url) for rating, beer_id in returned_checkins: tuple_to_insert = (rating, beer_id) try: client.execute(f'INSERT INTO beer_reviews VALUES ') except errors.ServerException as E: print(E) count += 1

С кнопками на этом всё. Постепенно мы формируем отличный датасет для последующего анализа, который рассмотрим в следующем цикле статей, как только завершим сбор данных — возможно, через месяц.

Python-сообщество

[RSS Feed]

  • Начало
  • » Python для новичков
  • » Как «нажать кнопку»?

#1 Ноя. 19, 2017 14:58:57

DenAon От: Ярославль Зарегистрирован: 2017-11-17 Сообщения: 5 Репутация: 0 Профиль Отправить e-mail

Как «нажать кнопку»?

Изучаю Python 3 и Selenium Webdriver.
Есть страница с Яндека, картинки https://yandex.ru/images/
Нужно нажать кнопку для перехода на картинку предыдущего дня

try: 
elem2 = driver.find_element_by_class_name("b-501px-slider__arrow b-501px-slider__arrow_dir_prev")
except NoSuchElementException:
qwe = input("Не нашлось кнопки Назад. Нажмите Enter для выхода")
else:
print("Переход по кнопке Назад")

Происходит исключение.
Как я понимаю проблемы могут быть следующие:
1. кнопка не видимая, нужно навести на нее мышку и нажать.
2. здесь срабатывает не нарисованная кнопка, а другой элемент, которому и надо передавать событие нажатия.

Прошу задать ускорение в нужную сторону.

Многознание уму не научает.

#2 Ноя. 20, 2017 19:38:19

hvppydvddy Зарегистрирован: 2015-05-26 Сообщения: 36 Репутация: 0 Профиль Отправить e-mail

Как «нажать кнопку»?

DenAon

elem2 = driver.find_element_by_xpath("/html/body/div[6]/div[1]/div/div[1]/div[3]/div[4]/div[1]/div") driver.execute_script("$(arguments[0]).click();", elem2) print("Переход по кнопке Назад") 

Отредактировано hvppydvddy (Ноя. 20, 2017 19:46:30)

#3 Ноя. 20, 2017 19:57:42

DenAon От: Ярославль Зарегистрирован: 2017-11-17 Сообщения: 5 Репутация: 0 Профиль Отправить e-mail

Как «нажать кнопку»?

hvppydvddy
DenAon

Благодарю за ответ. Я уже успел кой чего приколхозить, основная проблема была в том что я смотрел функцию хрома “посмотреть код”. Он показывал вот такой код
Но когда подсвечивается элемент при выделении кода, на экране он уже обозван как
div.b-501px-slider__arrow.b-501px-slider__arrow_dir_prev
Вместо пробела точка.
второй прикл, что эта кнопка при первой загрузке подсвечена и имеет вот такой код
Он отличается от того что я искал и нажимал.
В итоге пришлось сделать задержку и после нее искать элемент и нажимать.

time.sleep(1) 
try:
elem2 = driver.find_element_by_class_name("b-501px-slider__arrow.b-501px-slider__arrow_dir_prev")
except NoSuchElementException:
qwe = input("Не нашлось кнопки Назад. Нажмите Enter для выхода")
else:
print("Переход по кнопке Назад")
Click = ActionChains(self.driver).click(elem2)
Click.perform()

Еще подскажите каким инструментом можно найти правильный XPATH для элемента. А то из просмотра кода что то он совсем не видится. Или я не там смотрю.

Многознание уму не научает.

#4 Ноя. 20, 2017 20:02:58

hvppydvddy Зарегистрирован: 2015-05-26 Сообщения: 36 Репутация: 0 Профиль Отправить e-mail

Как «нажать кнопку»?

DenAon
ще подскажите каким инструментом можно найти правильный XPATH для элемента

Фаерфокс с этим справляется на ура) в старых версиях (если не ошибаюсь ниже 50) это аддон Fire Bug + FirePath. А на последней версии вообще сказка без всяких аддонов, ПКМ по элементу -> Исследовать элемент, снизу на выделенной строчке жмем ПКМ -> копировать -> Xpath

Отредактировано hvppydvddy (Ноя. 20, 2017 20:03:37)

#5 Ноя. 20, 2017 20:14:09

DenAon От: Ярославль Зарегистрирован: 2017-11-17 Сообщения: 5 Репутация: 0 Профиль Отправить e-mail

Как «нажать кнопку»?

hvppydvddy

Круто, буду знать! Полезный совет.

Многознание уму не научает.

[RSS Feed]

  • Начало
  • » Python для новичков
  • » Как «нажать кнопку»?

Python Selenium Иммитировать нажатие на кнопку «я не робот» recaptcha v2

Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно.
Необходимо обновить браузер или попробовать использовать другой.

themixa
Новичок

Пользователь
Май 13, 2020 14 0 1

Windows 10 , Python 3.9.5 , Хочу иммитировать нажатие на копку «я не робот» recaptcha v2. Но выдает ошибку : selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified ; «объект не допустим или закрыт» подскажите как обойти recaptcha v2 и нажать «я не робот» . Спасибо

import webbrowser,time,os,pyautogui
import selenium.common.exceptions
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import random
import os
from selenium.webdriver.chrome.options import Options

Как нажать на кнопку Selenium?

введите сюда описание изображения

Здраствуйте, имеется такая кнопка: Я хочу на нее сделать клик, вот код —

chrome.find_element_by_xpath('//input[@value="Выберите файл. "]').click()

В итоге имею такую ошибку:

selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable

Как это сделать? Кнопка кликабельна мышью

Отслеживать

задан 7 сен 2021 в 0:41

Vladimir Maksymchuk Vladimir Maksymchuk

57 2 2 серебряных знака 12 12 бронзовых знаков

Выведите на печать весь этот элемент прямо из кода. Сравните с тем, что видите в инспекторе. Терзают смутные сомнения, что вы слишком быстро добираетесь до кнопки и в момент обращения к ней она отключена. Возможно, в классах элемента установлен какой-то класс для отключения кнопки в этот момент или имеется соответствующий аргумент тега.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *