Как нажать на кнопку на сайте через Python?
Есть сайт, на котором некоторые элементы страницы недоступны до нажатия на кнопку. Адрес при нажатии при этом не меняется, поэтому нельзя просто перейти на другую страницу. Как это сделать? Какие библиотеки нужны?
Отслеживать
задан 21 дек 2019 в 19:05
IceCube092 IceCube092
43 1 1 серебряный знак 8 8 бронзовых знаков
Нет баллов на коммент, поэтому так. Это должно помочь: stackoverflow.com/questions/27869225/…
21 дек 2019 в 19:13
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Для подобных целей есть selenium.
Вот небольшой пример авторизации в вк.
from time import sleep from selenium import webdriver VK_ROOT_URL = "https://vk.com/" class TestFunc(object): def __init__(self): self.driver = webdriver.Firefox() self.driver.get(VK_ROOT_URL) def login(self, username, password): email_field = self.driver.find_element_by_id("index_email") email_field.send_keys(username) sleep(5) password_field = self.driver.find_element_by_id("index_pass") password_field.send_keys(password) sleep(5) login_button = self.driver.find_element_by_id("index_login_button") login_button.click() if __name__ == __main__: username = 'username' password = 'password' TestFunc().login(username, password)
Для марса у селенитам есть такая функция как get_attribute(«outerHTML»), которая возвращает HTML. В вашем распоряжении есть большая документация.
Обрабатываем нажатие кнопки в 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
Одним из наиболее используемых компонентов в графических программах является кнопка. В tkinter кнопки представлены классом Button . Основные параметры виджета Button:
- command : функция, которая вызывается при нажатии на кнопку
- compund : устанавливает расположение картинки и текста относительно друг друга
- cursor : курсор указателя мыши при наведении на метку
- image : ссылка на изображение, которое отображается на метке
- pading : отступы от границ вилжета до его текста
- state : состояние кнопки
- text : устанавливает текст метки
- textvariable : устанавливает привязку к элементу StringVar
- underline : указывает на номер символа в тексте кнопки, который подчеркивается. По умолчанию значение -1, то есть никакой символ не подчеркивается
- width : ширина виджета
Добавим в окно обычную кнопку из пакета ttk:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") # стандартная кнопка btn = ttk.Button(text="Button") btn.pack() root.mainloop()
Для создания кнопки используется конструктор Button() . В этом конструкторе с помощью параметра text можно установить текст кнопки.
Чтобы разместить виджет в контейнере (главном окне), у него вызывается метод pack() . На ОС Windows мы получим следующую кнопку:

Конструктор Button определяет различные параметры, которые позволяют настроить поведение и внешний вид кнопки. Однако конкретный набор параметров зависит от того, используем ли мы кнопки из пакета tkinter или из пакета tkinter.ttk.
Обработка нажатия на кнопку
Для обработки нажатия на кнопку необходимо установить в конструкторе параметр command , присвоив ему ссылку на функцию, которая будет срабатывать при нажатии:
from tkinter import * from tkinter import ttk clicks = 0 def click_button(): global clicks clicks += 1 # изменяем текст на кнопке btn["text"] = f"Clicks " root = Tk() root.title("METANIT.COM") root.geometry("250x150") btn = ttk.Button(text="Click Me", command=click_button) btn.pack() root.mainloop()
Здесь в качестве обработчика нажатия устанавливается функция click_button. В этой функции изменяется глобальная переменная clicks, которая хранит число кликов. Кроме того, изменяем текст кнопки, чтобы визуально было видно сколько нажатий произведено. Таким образом, при каждом нажатии кнопки будет срабатывать функция click_button, и количество кликов будет увеличиваться:

Отключение кнопки
Для ttk-кнопки мы можем установить отключенное состояние с помощью метода state() , передав ему значение «disabled». С такой кнопкой пользователь не сможет взаимодействовать:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") btn = ttk.Button(text="Click Me", state=["disabled"]) btn.pack() root.mainloop()
При этом в метод state мы можем передать набор состояний, поэтому значение «disabled» передается внутри списка.
Урок 3.3. Нажми на кнопку.
В рамках данного урока вы научитесь использовать функцию, с помощью которой можно завершить цикл при нажатии на кнопку. Эта функция доступна в языке TI-Nspire, поэтому для программирования на Python вам придется подгружать один или несколько специальных модулей.
Вы научитесь:
- Использовать функцию get_key() для завершения цикла
- Работать со степенями чисел 2 и 1/2
- Использовать функцию sleep(n) для приостановки выполнения кода на n секунд
Так как вы уже умеете работать с циклом оператора while, давайте попробуем использовать эффективную и интересную функцию системы TI-Nspire Python — get_key(). Вам необходимо написать программу, которая будет последовательно отображать степени числа 2 (например, 2, 4, 8, 16, 32, 64. ), и этот процесс будет продолжаться до тех пор, пока пользователь не нажмет на кнопку esc.
Примечание для учителя: функция get_key() включена в модуль ti_system. Она очень часто используется при работе с программами рисования и построения графиков (мы об этом расскажем в последующих уроках) и программами для микроконтроллера TI-Innovator™ Hub (об этом устройстве в данном курсе рассказано не будет).
Выражение from ti_system import get_key позволяет использовать данную функцию в любой программе. В этом модуле есть много других функций. Для дополнительной информации можете ознакомиться с документацией на сайте.
Операторы get_key() или get_key(0) проверяют, нажата ли определенная кнопка, при этом выполнение программы не прекращается.
Функция get_key(1) приостанавливает программу и ожидает нажатия на соответствующую кнопку.
1. Сначала создайте новую программу Python и выберите ее тип — «Пустая программа» (blank program). Назовите ее powers_of_2.
2. Используйте меню: menu > More Modules > TI System, чтобы вставить следующее выражение:
from ti_system import *
Его можно найти вверху списка.
В том же самом меню выберите следующее выражение:
while get_key() != «esc»:
block

3. Теперь вставьте переменную num = 2 непосредственно перед выражением while.

4. В блоке цикла (block) добавьте функцию ввода числа print и оператор присваивания, который будет умножать число на 2. Не забудьте структурировать свои операторы.
Попытайтесь сделать это самостоятельно перед тем, как приступить к проверке кода в следующем шаге.

Примечание для учителя: Для этого используются выражения num=num*2 или num*=2.
5. Вот, что должно получиться.
while get_key() != «esc»:
print(num)
num = num * 2
Запустите программу и нажмите на кнопку esc, если нужно ее остановить.

6. Вычисление будет происходить очень быстро!
Обратите внимание на две интересные особенности Python:
- Программы работают действительно быстро, и нет верхнего предела для целых чисел.
- Однако пользователь все же ограничен объемом памяти компьютера.
Ваша следующая задача — приостановить процесс вычисления, чтобы удобно было следить за числами.

7. Для этого вам понадобится функция sleep(), ее можно найти в модуле Python, который называется time.
Вверху своей программы добавьте следующее выражение:
from time import sleep
его можно найти в меню: menu > More Modules > Time, пункт time будет сверху.

8. Под выражением num = num * 2 добавьте следующий оператор:
sleep(1)
все это находится в блоке оператора while (и все три выражения в нем необходимо структурировать).
Снова запустите программу. На этот раз после того, как будет отображаться каждое число, компьютер будет останавливаться (и ждать) на одну секунду, а потом продолжит выполнять последовательность цикла. Можете изменить время паузы в выражении sleep, чтобы процесс шел немного быстрее. Снова нажмите esc, чтобы завершить выполнение программы. Попробуйте вписать и другие значения для оператора sleep(), чтобы изменять время отображения.
В конце программы напишите Done (Выполнено).

9. Замените каждую 2 в программе на 0.5.
- Что произойдет?
- Попробуйте ввести и другие цифры.
- В каких случаях числа увеличиваются, а в каких уменьшаются?
- Что вы можете сказать об отрицательных числах?
- Имеет ли смысл подставлять 0 или 1 вместо 2?
А теперь попробуйте сделать следующее: замените выражение num = num * 2 на num *= 2.
Данная операция быстрого ввода выполняет то же самое действие и доступна для работы со многими другими математическими операторами.

Примечание для учителя: Функции get_key() и sleep() являются дополнительными в программировании на языке Python, и этим они делают процесс работы разнообразнее и интереснее. Модуль time — это стандартный модуль Python, в котором содержатся и другие функции, связанные с управлением временем операций. Модуль ti_system является модулем Texas Instruments, он создан для работы только с операционной системой TI-Nspire CX II-Т.