Webbrowser schließen mit python

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
DominikD
User
Beiträge: 4
Registriert: Samstag 26. Dezember 2020, 20:30

Guten Tag,

ich schreibe gerade ein Programm welches bei Tastendruck eine Website öffnet und in dieser ein paar Dinge ausgefüllt und abgeschickt werden.
Das funktioniert auch.

Nun möchte ich, dass nach dem Abschließen, der Webbrowser auch geschlossen wird.
Als Webbrowser wird Chromium benutzt.

Gibt es eine einfache Methode, welche den Browser komplett schließt?

LG Dominik
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit dem extra zu installierenden Tool psutil den prozess es Browsers finden, und beenden
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

DominikD hat geschrieben: Sonntag 27. Dezember 2020, 17:11 Gibt es eine einfache Methode, welche den Browser komplett schließt?
Wie genau startest du den Browser denn und wie erfolgt das Ausfüllen? Das 'webbrowser'-Modul ist sehr komfortabel, aber leider eine Blackbox, die kaum Einflussmöglichkeiten bietet. Wenn es zum Beispiel eh nur auf deinem Rechner mit einem konkreten Browser funktionieren muss, kannst du diesen auch direkt mit dem 'subprocess'-Modul starten und beenden. Weiterhin ist die Frage, ob wirklich ein Browser benötigt wird (z. B. weil JavaScript zwingend benötigt wird), oder ob nicht vielleicht auch ein Post-Request reicht, wenn es nur darum geht, ein Formular aufzufüllen und abzusenden oder so ählich.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und selbst wenn man tatsächlich einen Browser braucht, könnte man auch erst einmal schauen ob Selenium ein Weg wäre.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
pumukel
User
Beiträge: 5
Registriert: Samstag 24. März 2018, 17:32

Hallo Dominik,
den Browser kannst du recht einfach schließen.
Du liest mit popen das Ergebnis von "ps axuw" in eine Variable, suchst dort den Browser und schließt ihn mit einem "sudo killall xxx" (xxx steht für den Browsernamen).
Vorab kannst du dir das im Terminalfenster ja mal mit "ps axuw" anschauen und auch testen.

Gruß pumukel
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pumukel: Zwischen dem von __deets__ vorgeschlagenen `psutil`-Modul und dem starten von externen Programmen ist `psutil` eindeutig die bessere Lösung.

Was soll denn das ``sudo`` in dem ganzen? Das ist ja der Browser den der Benutzer selber gestartet hat, da braucht man sicherlich nicht mehr Rechte als der Benutzer schon hat.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
DominikD
User
Beiträge: 4
Registriert: Samstag 26. Dezember 2020, 20:30

Code: Alles auswählen

#!/usr/bin/python3

import RPi.GPIO as GPIO
import time

import os
from selenium import webdriver 


GPIO.setwarnings(False)
gpio = 5
sw_in = 10


def main():
    
    print ("Warte auf Knopfdruck")
    print("")
    
    value = 0
    while True:
        
        if not GPIO.input(gpio):
            
            value += 0.01
        
        if value > 0 :
            
            if GPIO.input(gpio):
                
                print ("Knopf wurde gedrückt")
                print ("")
                driver = webdriver.Chrome()
        
                driver.get('https://mail.google.com/')
        
                print ("Gmail wurde geöffnet")
                print ("")
        
                mail_elem = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input")
                mail_elem.clear
                mail_elem.send_keys('maxmustermann@gmail.com')
                
                main()
                
        time.sleep(0.03)
    
    return 0

if __name__ == '__main__':
    
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(gpio, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
    main()
     
#Das ist das Script. Nach dem Ausfüllen der Website soll Chrome geschlossen werden und dann soll wieder auf den nächsten Knopfdruck gewartet werden.
#In der Zukunft soll dieses Programm beim Starten des PY ausgeführt werden und in Dauerschleife laufen
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Emails empfangen und senden kann man auch ohne solche wenig robusten und byzantinischen Konstruktionen.

Zb hier diskutiert: https://stackabuse.com/how-to-send-emai ... ng-python/
DominikD
User
Beiträge: 4
Registriert: Samstag 26. Dezember 2020, 20:30

__deets__ hat geschrieben: Mittwoch 30. Dezember 2020, 15:03 Emails empfangen und senden kann man auch ohne solche wenig robusten und byzantinischen Konstruktionen.

Zb hier diskutiert: https://stackabuse.com/how-to-send-emai ... ng-python/
Das war jetzt auf Gmail umgeschrieben, damit die genaue Website nicht genannt wird. Ist für eine Alarmanlage :)
Beim Alarm wird die Taste sozusagen gedrückt und dann wird der Alarm mittels Browser an das Handy weitergeleitet.
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Joa. Wenn man nicht sagt, was man wirklich vorhat, dann verschwendet man halt die Zeit von denjenigen, die einem helfen wollen. Super!

Und im Zweifel kann man auch deine Alarmanlage direkt via Python und http ansprechen, ohne so durch die Brust ins Auge zu schiessen.
DominikD
User
Beiträge: 4
Registriert: Samstag 26. Dezember 2020, 20:30

Hab es jetzt herausgefunden.

Code: Alles auswählen


driver.close()

Danach wird der Browser geschlossen :)
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Warnungen sind dazu da, dass man die Ursache behebt und nicht, dass man sie ignoriert. Der Rekursive Aufruf von main ist ein Programmierfehler.
Statt dieses unsinnige Warten per Loop sollte man das per Funktion machen. Warum wird value um 0.01 erhöht? Warum nicht 16.432352935?
Und wie immer wird dieses idiotische `as` beim Import ohne Nachdenken kopiert.

Code: Alles auswählen

#!/usr/bin/python3
from RPi import GPIO
from selenium import webdriver 

BUTTON_PIN = 5

def do_something():
    driver = webdriver.Chrome()
    driver.get('https://mail.google.com/')
    print("Gmail wurde geöffnet")
    mail_elem = driver.find_element_by_xpath("/html/body/div[1]/div[1]/div[2]/div/div[2]/div/div/div[2]/div/div[1]/div/form/span/section/div/div/div[1]/div/div[1]/div/div[1]/input")
    mail_elem.send_keys('maxmustermann@gmail.com')

def main():
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(gpio, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
    try:
        while True:
            print("Warte auf Knopfdruck")
            GPIO.wait_for_edge(BUTTON_PIN, GPIO.RISING)
            print ("Knopf wurde gedrückt")
            do_something()
    finally:
        GPIO.cleanup()
    
if __name__ == '__main__':
    main()
pumukel
User
Beiträge: 5
Registriert: Samstag 24. März 2018, 17:32

Hallo blackjack,
warum stört dich das "sudo"? Dem Raspi tut das nicht weh. Ich habe keine Ahnung, mit welchen Rechten Dominik seine Scripte startet. Mit "sudo" klappt das Beenden aber auf jeden Fall. Der Raspi springt ihm für diese "Mehrarbeit" auch nicht ins Gesicht.

pumukel
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist Cargo cult Programmierung. Sudo hat mal irgendwo geholfen, also Streut man es wie Salz über alles mögliche, in der Hoffnung, die Pampe die man angerührt hat, wird genießbar. Das Problem ist ganz einfach, das man sich so Probleme einhandelt. Zb überschriebene System-Pakete, gelöschte Dateisysteme, etc.

Geht davon die Welt unter? Nein. Macht man sich und anderen unnötig Arbeit, die dann mühselig wiederholt werden muss? Ja. Kann man also vor warnen. Vor allem diejenigen, die es nicht besser wissen.
Benutzeravatar
joernius
User
Beiträge: 31
Registriert: Donnerstag 11. Juni 2020, 13:47
Wohnort: Dresden
Kontaktdaten:

Code: Alles auswählen

ps -ef|grep -v grep|grep MEIN_PROGRAMM|tr -s " "|cut -d" " -f2|xargs kill
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@joernius: Umständlich und je nach Programmname und was da so läuft auch gefährlich kaputt. Je kürzer der Programmname desto wahrscheinlicher das als Kollateralschaden noch ganz andere Prozesse beendet werden. Sollte der Programmname zufällig im Namen des Benutzers enthalten sein, dann werden sogar *alle* Prozesse von dem Benutzer beendet.

Das Problem ist durch `driver.close()` je bereits einfach und sicher gelöst. Aber falls man wirklich selbst nach dem Namen beenden will, dann gibt es das bereits erwähnte `psutil`-Modul

Code: Alles auswählen

#!/usr/bin/env python3
from signal import SIGKILL, SIGTERM

import psutil


def send_signal(processes, signal):
    for process in processes:
        try:
            process.send_signal(signal)
        except psutil.NoSuchProcess:
            pass


def main():
    processes = [
        process
        for process in psutil.process_iter()
        if process.name() == "firefox"
    ]
    send_signal(processes, SIGTERM)
    _, still_alive = psutil.wait_procs(processes, 3)
    send_signal(still_alive, SIGKILL)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Hinzu kommt, dass man ps nur selten in Kombination mit grep braucht, denn dafür gibt es pgrep oder pidof, sowie weiterhin pkill, das auf Basis von Namensbestandteilen operiert. Die gezeigte Pipeline ist äquivalent zu pkill -f <prozessname>. Ich würde das aber wie ja schon mehrfach gesagt wurde gar nicht so machen.
Antworten