Web Scraping

Kirby_Sike

Kirby_Sike

Top Contributor
Also ich versuche eine Webseite zu scrapen und bekommen beim verbinden die Exception: 403 welche einfach bedeutet dass mir der Zugriff verwehrt wird (forbidden access)...Ich vermute ich brauche den csrf token :) Ich hoffe ihr könnt mir etwas helfen xD

Es ist zwar eigentlich Python, aber mir geht es eher darum den csrf_token im Web Browser zu finden xD
 
Kirby_Sike

Kirby_Sike

Top Contributor
Ich poste einfach mal Quellcode :)

Das ist der Code:
Python:
import requests
from bs4 import BeautifulSoup as bs

def loginToPage():
    print("Getting HTML Login ready!")

def getImage():
    print("Fetching Image from Folder")

def postImage():
    print("Posting image!")

with requests.Session() as s:
    site = s.get("https://www.instagram.com")
    try:
        site = s.get("https://www.instagram.com")
        # If the response was successful, no Exception will be raised
        site.raise_for_status()
    except s.HTTPError as http_err:
        print(f'HTTP error occurred: {http_err}') 
    except Exception as err:
        print(f'Other error occurred: {err}') 
    else:
        print('Successfully opened Webpage!')

    bs_content = bs(site.content, "html.parser")
    login_data = {"username":"testacc","password":"test"}
    try:
        response = s.post("https://www.instagram.com",login_data)
        response.raise_for_status()
    except s.HTTPError as http_err:
        print(f'HTTP error occurred: {http_err}') 
    except Exception as err:
        print(f'Other error occurred: {err}') 
    else:
        print('Successfully logged in!')

    home_page = s.get("https://www.instagram.com/instagram/")

Das ist die Fehlermeldung:

Code:
Successfuly open Webpage!
Traceback (most recent call last):
  File "bot.py", line 31, in <module>
    response.raise_for_status()
  File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/requests/models.py", line 941, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://www.instagram.com/

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "bot.py", line 32, in <module>
    except s.HTTPError as http_err:
AttributeError: 'Session' object has no attribute 'HTTPError'
 
Kirby_Sike

Kirby_Sike

Top Contributor
Also ich habe gerade gefunden wie es mit BeautifulSoup funktionieren sollte :)
Python:
    bs_content = bs(site.content, "html.parser")
    token = bs_content.find("input", {"name":"csrf_token"})["value"]
    login_data = {"username":"","password":"", "csrf_token":token}

Jedoch kommt dann diese Fehlermeldung:

Code:
Successfully opened Webpage!
Traceback (most recent call last):
  File "bot.py", line 28, in <module>
    token = bs_content.find("input", {"name":"csrf_token"})["value"]
TypeError: 'NoneType' object is not subscriptable
 
sascha-sphw

sascha-sphw

Bekanntes Mitglied
Hast Du denn mal versucht was in dem Link von @M.L. steht?

Da Du ja einen GET Request absetzt bezweifel ich das es was mit dem CSRF Token zu tun hat.
 
Kirby_Sike

Kirby_Sike

Top Contributor
Also ich habe mir den Thread etwas durchgelesen, jedoch benutze dort alle andere Module xD So wie ich es verstanden habe, muss ich der Webseite vorgaukeln, dass ich ein Webbrowser, wie z.B. Mozilla Firefox 5.0 bin, um nicht als Bot/Spider erkannt zu werden :) Soweit so gut jetzt müsste ich nur noch einen Weg finden es mit meinem Module hinzukriegen xD

Edit: Für die GET habe ich nun einen User Agent hinzugefügt
Python:
user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
    headers = {'User-Agent': user_agent}
    site = s.get("https://www.instagram.com")
    try:
        site = s.get("https://www.instagram.com", headers=headers)
        site.raise_for_status()
    except HTTPError as http_err:
        print(f'HTTP error occurred: {http_err}')
    except Exception as err:
        print(f'Other error occurred: {err}')
    else:
        print('Successfully opened Webpage!')

Bei der POST bin ich mir der Syntax nicht sicher und google gerade noch :)

Edit: Ich habe noch nicht verwertbares gefunden, jedoch hatte ich einfach mal ausprobiert es in die Login Daten Liste zu stecken...leider war das nicht richtig xD

Python:
    login_data = {"username":"test","password":"test", "User-Agent": user_agent}

    try:
        response = s.post("https://www.instagram.com",login_data)
        response.raise_for_status()
    except HTTPError as http_err:
        print(f'HTTP error occurred: {http_err}') 
    except Exception as err:
        print(f'Other error occurred: {err}') 
    else:
        print('Successfully logged in!')
 
Zuletzt bearbeitet:
Kirby_Sike

Kirby_Sike

Top Contributor
Soooo ich habe mir einfach mal die Doku durchgelesen, jedoch kann ich wenig damit anfangen und verstehe nicht wirklich wo ich jetzt user agent mit rein stecken könnte :(

Hier ist ein Screenshot:
Bildschirmfoto 2020-04-14 um 20.03.46.png
 
T

thecain

Top Contributor
Lesen...
  • **kwargs -- Optional arguments that request takes.

Wie wärs bei .request zu lesen?

  • headers -- (optional) Dictionary of HTTP Headers to send with the Request.

Gefunden! Und vor 30 Sec hab ich das noch nicht gewusst.
 
Kirby_Sike

Kirby_Sike

Top Contributor
Ich habe es ja schon in einen Header gesteckt :) Jedoch wenn ich versuche es zu verwenden (so wie ich es glaube) komm halt diese Meldung:
Code:
Successfully opened Webpage!
Other error occurred: post() takes from 2 to 4 positional arguments but 5 were given

Das POST Statement sieht jetzt so aus:

Python:
response = s.post("https://www.instagram.com",login_data, None, headers)
 
T

thecain

Top Contributor
Wieso mit python wenn du kein python kannst?
Python:
response = s.post("https://www.instagram.com",login_data, headers=headers)
 
Kirby_Sike

Kirby_Sike

Top Contributor
Weil ich es gerne lernen möchte und meistens etwas lerne, indem ich es einfach tue und versuche es nachzuvollziehen :)
 
Kirby_Sike

Kirby_Sike

Top Contributor
Ich werde mir einfach morgen mal die Instagram API durchlesen und es über die API machen
 
Kirby_Sike

Kirby_Sike

Top Contributor
Sooo ich habe gestern Nacht ein sehr schöne Bibliothek für Web Scraping gefunden :) ---> Selenium

Damit funktioniert es super :)
 
Kirby_Sike

Kirby_Sike

Top Contributor
Na da hat man wieder etwas neues dazu gelernt xD Du hast ja Recht, aber wirklich schnell muss der "Bot" nicht sein xD Er muss lediglich zu bestimmten Zeiten angeschmissen werden, ein Formular ausfüllen und hat dafür so viel Zeit wie er braucht :) Im Durchschnitt braucht er 10 sec xD
 
Kirby_Sike

Kirby_Sike

Top Contributor
Alsooo habe alles mehr oder weniger fertig :) Jetzt kommt halt der Part wo der Bot ein Bild hochladen soll :)

Der Bot clickt erfolgreich auf den Upload Button und dann öffnet sich ein Finder-Window (Mac :) ). Wie könnte ich das nun auch automatisieren? Soll ich einfach im Code einen Ordner angeben, welchen der Bot aufruft und sich dann die Dateien holt? Man könnte doch "os" verwenden oder gibt es noch etwas besseres?

Ich sende einfach mal meinen bisherigen Code :

Python:
from time import sleep
from selenium import webdriver

class InstBot():

    def __init__(self,username, pw):
        self.username = username
        self.pw = pw
        mobile_emulation = {"deviceName": "Nexus 5"}
        options = webdriver.ChromeOptions()
        options.add_experimental_option("mobileEmulation", mobile_emulation)
        self.driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=options)
        self.driver.get("https://www.instagram.com")

        sleep(2)

        closeCookie = self.driver.find_element_by_xpath("/html/body/div[1]/section/div[1]/button").click()  #Cookie Close
        getToLogin = self.driver.find_element_by_xpath("/html/body/div[1]/section/main/article/div/div/div/div[2]/button").click()  #Go to Login

        sleep(1)

        login_field = self.driver.find_element_by_xpath("/html/body/div[1]/section/main/article/div/div/div/form/div[4]/div/label/input")\
        .send_keys(username) #Username Field
        login_field2 = self.driver.find_element_by_xpath("/html/body/div[1]/section/main/article/div/div/div/form/div[5]/div/label/input")\
        .send_keys(pw) #Password Field
        self.driver.find_element_by_xpath("/html/body/div[1]/section/main/article/div/div/div/form/div[7]").click()  #Login Button

        sleep(2)

        self.driver.find_element_by_xpath("/html/body/div[1]/section/main/div/div/div/button").click() #Close Pop_Up 1

        sleep(1)

        self.driver.find_element_by_xpath("/html/body/div[4]/div/div/div[3]/button[2]").click()  #Close Pop-Up 2

        sleep(1)

        self.driver.find_element_by_xpath("/html/body/div[1]/section/nav[2]/div/div/div[2]/div/div/div[3]").click()

        print("Bot successful!")
    
    def getUserName(self):
        print(self.username)

a = InstBot('test', 'test')
 
Zuletzt bearbeitet:
Kirby_Sike

Kirby_Sike

Top Contributor
Edit: Alsooo alle Error Meldungen sind behoben :) Das Problem daran ist, dass trotzdem keine Datei hochgeladen wird xD Wie kann ich das debuggen? Muss ich das im Browser machen? BTW ich nutze Chrome :)
 
Kirby_Sike

Kirby_Sike

Top Contributor
Edit: Ich habe eine Vermutung warum es nicht geht...ich habe gerade einen Thread auf StackOverflow gelesen und dort wurde geschrieben, dass man den "MacOS"-Fester-Dialog part überspringen sollte und den direkten upload über den absoluten Pfad machen soll xD Ich habe vermutlich einfach den falschen xPath in meinem Statement :)
 
Kirby_Sike

Kirby_Sike

Top Contributor
@Robat Du kennst dich doch ziemlich gut mit HTML aus xD Hier das sind die einzigen Elemente die im Source Code sichtbar sind :)
Bildschirmfoto 2020-04-17 um 10.49.07.png
 
Robat

Robat

Top Contributor
Das hat mEn weniger was mit HTML Kenntnissen zu tun sondern eher was mit Selenium/Python Kenntnissen.

Ich musste bisher nur einmal sowas in Selenium machen (zum Glück).. Da ging es mEn mit der send_keys() Methode. Lt. Stackoverflow scheint das auch noch so zu sein
 
Kirby_Sike

Kirby_Sike

Top Contributor
Das hat mEn weniger was mit HTML Kenntnissen zu tun sondern eher was mit Selenium/Python Kenntnissen.

Ich musste bisher nur einmal sowas in Selenium machen (zum Glück).. Da ging es mEn mit der send_keys() Methode. Lt. Stackoverflow scheint das auch noch so zu sein
Ich habe es genau so, nur halt mit xPath xD Ich würde mich ja wenigstens über eine Fehlermeldung freuen, aber es kommt nichts...nur die Meldung das alles funktioniert hat...was nicht ganz der Fall ist XD Naja ich werde schon irgendwas was finden
 
B

Barista

Bekanntes Mitglied
Sooo ich habe gestern Nacht ein sehr schöne Bibliothek für Web Scraping gefunden :) ---> Selenium

Ich habe einige Zeit (Jahre) von einer Merchandising-Website Preise und Bilder mit Selenium eingelesen.

Irgendwann haben die auf jede Menge Ajax umgestellt und es klappte damit nicht mehr.

Ich habe java.awt.Robot benutzt, das kann Screenshots machen sowie Tastendrücke und Mausklicks.

Bevor ich das Programm starte, muss ich den Browser starten und die gewünschte URL an-navigieren.

Nach dem Programmstart in Eclipse habe ich 10 Sekunden, um in das Browserfenster zu wechseln.

Bilder lese ich ein mit: rechte Maustaste -> Link kopieren, Laden von Link-URL.

Preise lese ich über: Tastatur Strg-A, Strg-C, Java-Clipboard, Preis aus Text rausparsen.

Irgendwie wäre künstliche Intelligenz cool, ich arbeite aber mit festen Bildschirm-Positionen, geht eben nur mit einem bestimmten Bildschrim und solange die Website gleich bleibt.
 
Kirby_Sike

Kirby_Sike

Top Contributor
XD bei mir öffnet Python die Webseite automatisch und navigieren tue ich per xpath :)
 
Anzeige

Neue Themen


Oben