Seite 1 von 1

Denkanstoß Webscraping

Verfasst: Freitag 27. Dezember 2019, 15:27
von Code Codain
Hallo Leute,

ich möchte am Wochenende ein kleines Projekt in Python verwirklichen. Und zwar möchte ich aus einer Excelliste eine Spalte mit Straßen einlesen und von einem bestimmten Standort die Entfernung in KM bestimmen. Da ich noch ein Anfänger bin und übelsten Spaghetticode produziere (von hinten durch Knie ins Auge), bräuchte ich mal ein paar Denkanstöße von den Profis. Bis jetzt habe ich überlegt, dass ich openpyxl fürs einlesen der Exceltabelle und requests für webscraping nutzten will (bzw. zusätzlich noch beautifullsoup). Vllt könnt ihr mir ein paar Tipps geben auf was ich achten sollte, was wichtige Punkte wären.

Vielen Dank und schon mal eine Guten Rutsch an Alle.
Code Codain.

Re: Denkanstoß Webscraping

Verfasst: Freitag 27. Dezember 2019, 15:59
von __blackjack__
Statt Webscraping würde ich da wohl erst einmal schauen ob es eine API dafür gibt.

Re: Denkanstoß Webscraping [solved]

Verfasst: Sonntag 29. Dezember 2019, 10:09
von Code Codain
__blackjack__ hat geschrieben: Freitag 27. Dezember 2019, 15:59 Statt Webscraping würde ich da wohl erst einmal schauen ob es eine API dafür gibt.
Danke für den Tip bzgl. der Api. Ich habs sogar hinbekommen :) Hast du eine Idee, wie man den Code noch verbessern könnte?

Code: Alles auswählen

import os
import openpyxl
import googlemaps
import requests
import json

key = 'AIzaSyBT1kaERkXXXXXXXXXXXXA'

os.chdir('E:\\Entfernung')
print (os.getcwd())

wb = openpyxl.load_workbook('Entfernung.xlsx')
sheet = wb['Tabelle1']

for row in range (1,90):
    celldestination = 'd' + str(row)
    strasse = (sheet[celldestination].value)
    gmaps = googlemaps.Client(key)
    destination = strasse
    url = 'https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=Beispielstrasse+115,+Berlin&destinations=%s, Berlin &key=%s' % (destination,key)
    r = requests.get(url)
    entfernung = json.loads(r.text)
    km = entfernung['rows'][0]['elements'][0]['distance']['text']
    celldistance = 'f' + str(row)
    sheet[celldistance] = km
    wb.save('test.xlsx')

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 10:23
von Sirius3
Bei URLs kodiert man nicht selbst sollte Parameter, sondern nutzt das param-Argument von requests.get.
chdir darf in einem ordentlichen Programm nicht vorkommen. In jedem Schleifendurchgang sollte selbe Excel-Datei zu schreiben, ist unsinnig. Das macht man einmal danach. Das response-Objekt kennt eine json-Methode. Konstanten schreibt man KOMPLETT_GROSS. Die URL sollte auch eine Konstante sein. Statt fix bis 90 zu gehen, sollte man das anhand der Inputdaten ermitteln. gmaps wird gar nicht verwendet und sollte, wenn doch vor der Schleife stehen. strasse hat zu viele Klammern, und warum wird sie in destination umbenannt? Die beiden celldestination sind eigentlich überflüssig, da man den Wert auch direkt nutzten könnte.

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 10:25
von Code Codain
@Sirius3

Perfekt, danke für den input. Werde den code entsprechend deinen infos korrigieren.

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 15:39
von Code Codain
Sirius3 hat geschrieben: Sonntag 29. Dezember 2019, 10:23 ....
Ich hab mal probiert deine vorschläge umzusetzten, vllt kannst du mal ein blick drauf werfen. etwas unglücklich bin ich noch mit der ZAEHLER lösung beim schreiben der ergebnisse in die zellen, kriege es aber iwie nicht anders hin.

Code: Alles auswählen

import openpyxl
import requests

KEY = 'AIzaSyBT1kaERknFXD6gRSXXXXX
ZAEHLER = 1

wb = openpyxl.load_workbook('Entfernung.xlsx')
sheet = wb['Tabelle1']

for cell in sheet['D']:
    street = (cell.value)
    payload = {'units' : 'metric', 'destinations' : street + 'Berlin', 'origins' : 'Musterstr+115,+Berlin', 'key': KEY}
    r = requests.get('https://maps.googleapis.com/maps/api/distancematrix/json', params=payload)
    antwort = r.json()
    entfernung = antwort['rows'][0]['elements'][0]['distance']['text']
    sheet['F'+ str(ZAEHLER)] = entfernung
    ZAEHLER = ZAEHLER + 1

wb.save('test.xlsx')

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 16:23
von Sirius3
Komplett gross geschriebene Variablennamen benutzt man nur für Konstanten. Wenn man einen Zähler zusätzlich in einer Schleife will, dafür gibt es ›enumerate‹. Das + in origins war nur dazu da, um Leerzeichen zu kodieren. Braucht man aber nicht mehr, wenn man params benutzt. Google ist zum Glück großzügig. Die Mischung aus englischen und deutschen Namen liest sich etwas holprig. Entscheide Dich für eine Sprache (Englisch).

Code: Alles auswählen

import openpyxl
import requests

KEY = 'AIzaSyBT1kaERknFXD6gRSXXXXX'
DISTANCE_URL = 'https://maps.googleapis.com/maps/api/distancematrix/json'
DISTANCE_PARAMS = {
    'units': 'metric',
    'origins': 'Musterstr. 115, Berlin',
    'key': KEY,
}

wb = openpyxl.load_workbook('Entfernung.xlsx')
sheet = wb['Tabelle1']

for row, cell in enumerate(sheet['D']):
    street = cell.value
    payload = dict(DISTANCE_PARAMS, destinations=f"{street}, Berlin")
    response = requests.get(DISTANCE_URL, params=payload)
    antwort = response.json()
    entfernung = antwort['rows'][0]['elements'][0]['distance']['text']
    sheet[f"F{row}"] = entfernung

wb.save('test.xlsx')

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 17:28
von Code Codain
Sirius3 hat geschrieben: Sonntag 29. Dezember 2019, 16:23 ...
Danke für den Beispielcode, ich bekomme ihn jedoch leider nicht zum laufen:

Code: Alles auswählen

Traceback (most recent call last):
  File "..\PyCharmCE2019.3/config/scratches/scratch_2.py", line 22, in <module>
    sheet[f"F{row}"] = entfernung
  File "..\PycharmProjects\MyProject\venv\lib\site-packages\openpyxl\worksheet\worksheet.py", line 309, in __setitem__
    self[key].value = value
AttributeError: 'tuple' object has no attribute 'value'
Hat es auch irgendeinen Hintergrund, dass du manchmal ' oder " nutzt? Hatte es so verstanden, dass die beiden Zeichen identisch sind.

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 17:38
von Sirius3
Ja, " und ' sind austauschbar. " liegt mir näher.

Muß wahrscheinlich von 1 ab laufen: `enumerate(sheet['D'], 1)`

Re: Denkanstoß Webscraping

Verfasst: Sonntag 29. Dezember 2019, 17:41
von Code Codain
Alles klar, hat übrigens geklappt mit (sheet['D'], 1). Du machst das schon ne Weile oder?