Forum: PC-Programmierung Daten von Webseite sammeln und verarbeiten


von Joss (Gast)


Lesenswert?

Hi

Ich versuche gerade folgendes:
AUf einer Webseite werden laufend neue Einträge (Transaktionen) 
veröffentlicht. Manchmal 3 pro Sekunde, manchmal 1 alle paar Minuten. 
Dabei werden bei jedem manuellen Refresh die 5 neusten angezeigt. Die 
Einträge haben zwar eine ID, die ist aber nicht fortlaufend.

Ich hab es nun geschafft, die Einträge mit Postman abzufragen. Ziel wäre 
es nun, die Einträge in eine eigene DB zu übernehmen, jedoch nur die 
noch nicht vorhandenen.

Jeder Eintrag besteht aus 8 Feldern, die immer die selbe html ID haben 
(<td id="Feld1"> usw.). Eines der Felder ist die eindeutige ID des 
Eintrags.

Man müsste nun laufend die 5 neusten Einträge abrufen und die jeweiligen 
IDs mit den vorhergehenden vergleichten, neue in die DB übernehmen. Ist 
zwar umstädnlich und unschön, aber eine andere Lösung fällt mir nicht 
ein.

Auf welche Tools würdet ihr zurückgreifen? Ich dachte mal an Python mit 
Selenium...

von Soupé (Gast)


Lesenswert?

Joss schrieb:
> Ich dachte mal an Python mit Selenium...

Python mit requests & BeautifulSoup.

Wenn die Website nicht so gestrickt ist, dass unbedingt eine GUI 
gebraucht wird, würde ich auf diese (und Selenium) verzichten.

von Soupé (Gast)


Lesenswert?

... und wenn du dafür die erforderlichen requests heraussuchst, findest 
du womöglich einen Weg mehr als nur die letzten 5 Einträge zu bekommen 
:-)

von A. S. (rava)


Lesenswert?

manche websites mögen es gar nicht, wenn du sie als Datenbasis 
missbrauchst ohne, dass sie dir ihre Werbung anzeigen dürfen. In dem 
Fall kommt einfach nichts raus, ohne richtigen Browser.
Dann musst du vielleicht eine Browser extension schreiben...

von Wendels B. (wendelsberg)


Lesenswert?

Joss schrieb:
> neue in die DB übernehmen

Alle DBs, mit denen ich bisher zu tun hatte, kennen einen Befehl wie 
"INSERT wenn noch nicht in DB".

von Joss (Gast)


Lesenswert?

ok, vielen Dank!

Kannte BeautifulSoup noch nicht...
Werde mich jetzt mal damit befassen. Jedoch nicht unter Windows sondern 
Linux

Welche Distro würdet ihr für solche Zwecke verwenden? CentOS? Ubuntu? ..

von c-hater (Gast)


Lesenswert?

Wendels B. schrieb:

> Alle DBs, mit denen ich bisher zu tun hatte, kennen einen Befehl wie
> "INSERT wenn noch nicht in DB".

Ähem... Nö.

Was alle haben, ist ein Mechanismus zur Verhinderung doppelter Einträge 
in Tabellen, z.b. Unique-Constraints oder Primary Keys (die Uniqueness 
implizieren).

Aber diese Mechanismen sorgen erstmal einfach nur dafür, dass der Insert 
fehlschlägt (mit entsprechender Fehlermeldung).

Vorher schauen und nur dann einfügen, wenn noch nicht vorhanden und 
ansonsten ohne Mecker nix machen, das muss man typisch erst bauen.

Und das ist garnicht so einfach, wie man denken mag. Insbesondere dann 
nicht, wenn es zuverlässig funktionieren soll (also auch bei 
möglicherweise konkurrierende Schreibzugriffen auf die gleiche Tabelle).

Um sowas umzusetzen gibt es verschiedene Ansätze. Ich persönlich 
bevorzuge die, die mit jeder SQL-DB gleichermaßen funktionieren, also 
ohne explizit formulierte Transaktionsrahmen auskommen.

Allerdings: längst nicht immer ist das auch die effizienteste Lösung. 
Wenn also zur Konkurrenz auch noch hohe Last hinzukommt, dann muss man 
gelegentlich von den schönen universellen Sachen abweichen.

Lastfragen dürften aber beim Problem des TO eher keine Rolle spielen. 
Konkurrenz hingegen möglicherweise schon. Manchmal muss man Webseiten 
nämlich einfach austricksen, um einigermaßen schnell an größere Mengen 
Daten zu kommen. Da läßt man dann einige Agenten von unterscheidlichen 
IP-Adressen aus agieren und führt deren Ergebnisse in einer gemeinsamen 
DB zusammen.

Nicht ganz fair, nicht ganz fein, aber sie wollen es ja offensichtlich 
genau so haben...

von Joss (Gast)


Lesenswert?

Die besagte Seite wird normalerweise im Browser durch einen Click auf 
einen Button angezeigt. Der Klick führt dann flgendes aus:

onclick="javascript:postAction('/Public/Tendering/ContractNoticeManageme 
nt/ResultListGoToPage?mkey=48617fb9_5cab_4d3b_b84d_a60ee045f0b4',  { 
startIdx: '5', endIdx: '9', pageNumber: '1', perspective: 'All', 
initAction: 'Index'})"


In Postman habe ich außer einen gültigen mkey in Params außerdem im Body 
startIdx, endIdx und pageNumber eingebaut, dann hat die Abfrage 
geklappt.
Wie mache ich das ganze in Python mit request?

von Helmut H. (helmuth)


Lesenswert?

Joss schrieb:
> Auf welche Tools würdet ihr zurückgreifen? Ich dachte mal an Python mit
> Selenium...

Habe sowas mit Python und Selenium gemacht, geht.
z.B.
1
 def login(self):
2
        d = self.driver
3
        d.get(self.base_url)
4
        d.find_element_by_link_text("Click here to log in").click()
5
        d.find_element_by_name("username").send_keys(self.myuser)
6
        d.find_element_by_name("password").send_keys(self.mypasswd)
7
        d.find_element_by_css_selector("fieldset > button.btn").click()
8
        print "Login using %s %s"%(self.myuser,self.mypasswd)

Auswerten kann etwas mühsam sein, hängt vom Aufbau der Webseite ab, aber 
Selenium bietet alle Möglichkeiten:
1
 def getMyOrders(self):
2
        self.driver.get(self.base_url+"trading")
3
        self.order=[]
4
        try:
5
            rem=self.driver.find_elements_by_class_name("info")
6
        except Exception as inst:
7
            print "getMyOrders info: "+str(inst)
8
            rem=[]
9
        for r in rem:       
10
            y=r.find_elements_by_tag_name("li")
11
            cu=y[1].get_attribute("currency")
12
            q=r.find_elements_by_xpath("td")
13
            tmp=q[4].text.split() 
14
      ...

: Bearbeitet durch User
von Nur_ein_typ (Gast)


Lesenswert?

Soupé schrieb:
> Joss schrieb:
>> Ich dachte mal an Python mit Selenium...
>
> Python mit requests & BeautifulSoup.

... oder womöglich Python mit Scrapy [1]. BeautifulSoup und requests 
habe ich früher auch benutzt, aber nachdem ich Scrapy entdeckt habe... 
damit gehen viele Dinge viel schneller und einfacher.

[1] https://scrapy.org/

> Wenn die Website nicht so gestrickt ist, dass unbedingt eine GUI
> gebraucht wird, würde ich auf diese (und Selenium) verzichten.

Selenium habe ich auch schon häufiger benutzt, insbesondere bei 
Webseiten, die sehr JavaScript-lastig waren. Das funktioniert zwar 
meistens, aber nicht immer stabil.

von Wendels B. (wendelsberg)


Lesenswert?


von Ein T. (ein_typ)


Lesenswert?


von c-hater (Gast)


Lesenswert?

Ein T. schrieb:

> ...oder PostgreSQL "INSERT ... ON CONFLICT ..." [1].

Ja, alles so schöne Spezialsachen, die nicht portabel sind.

Man kann das aber auch in plain old common SQL schreiben, so dass es für 
alle SQL-DBs funktioniert. Das ist, was dir aber die jeweiligen 
Hersteller nicht verraten. Diese Strategie nennt sich Vendor-LockIn.

Der Nachteil der universellen Lösung ist halt, wie schon gesagt, dass 
i.d.R. nicht das Optimum bezüglich der Performance damit erreicht werden 
kann. Muss man abwägen, was einem für die jeweilige Anwendung wichtiger 
ist: problemlose Migration auf eine andere DB oder Vmax.

von Nur_ein_typ (Gast)


Lesenswert?

c-hater schrieb:
> Ein T. schrieb:
>
>> ...oder PostgreSQL "INSERT ... ON CONFLICT ..." [1].
>
> Ja, alles so schöne Spezialsachen, die nicht portabel sind.

Ich glaube nicht, daß Portabilität für den TO besondere Priorität hat. 
Und auch, wenn das nicht portable Spezialitäten sind -- wobei SQLite 
ebenfalls diesbezüglich die Syntax von PostgreSQL zu unterstützen 
scheint und insofern eine gewisse Portabilität sogar durchaus vorhanden 
wäre -- ändert das nichts daran, daß es Datenbanken gibt, die diese 
Möglichkeiten bieten, was Du weiter oben rundheraus bestritten hattest. 
Und Du hattest es nicht mit dem Hinweis bestritten, daß das nicht 
portabel sei, sondern stattdessen einfach behauptet, daß es solche 
Befehle gar nicht gäbe. Die Portabilität scheint also für Dich jetzt 
nurmehr ein Vehikel zu sein, um zu verbergen und davon abzulenken, daß 
Du diese Möglichkeiten vorher einfach nicht gekannt hast, Du Dich nicht 
so gut mit Datenbanken auszukennen scheinst, wie Du tust, und daß es 
hier im Forum offenbar Leute gibt, die manche Dinge besser wissen als 
Du.

von Kolja L. (kolja82)


Lesenswert?

Nur_ein_typ schrieb:
> oder womöglich Python mit Scrapy [1]. BeautifulSoup und requests habe
> ich früher auch benutzt, aber nachdem ich Scrapy entdeckt habe... damit
> gehen viele Dinge viel schneller und einfacher.

Mhh, okay, ich fand den einstieg bei BS deulich angenehmer als bei 
Scrapy. Ist aber bestimmt Geschmackssache.

von Nur_ein_typ (Gast)


Lesenswert?

Kolja L. schrieb:
> Nur_ein_typ schrieb:
>> oder womöglich Python mit Scrapy [1]. BeautifulSoup und requests habe
>> ich früher auch benutzt, aber nachdem ich Scrapy entdeckt habe... damit
>> gehen viele Dinge viel schneller und einfacher.
>
> Mhh, okay, ich fand den einstieg bei BS deulich angenehmer als bei
> Scrapy. Ist aber bestimmt Geschmackssache.

Das ist sicherlich eine Geschmackssache, ich fand Scrapy sogar einfacher 
-- einmal das Tutorial durchgearbeitet und los ging es. Dafür nimmt 
Scrapy einem dann auch etliche, zum Teil durchaus tückische und / oder 
aufwändige Sachen ab: die Request- und Response-Zyklen mit Auswertung 
des Statuscode und automatischem Handling von Cookies und Sessions, 
Parallelisierung, Logging, die Speicherung der extrahierten Daten... Das 
muß man mit BeautifulSoup für Scraper alles selbst bauen, obgleich es 
für Einsteiger sehr lehrreich ist und sicherlich auch bei einer späteren 
Arbeit mit Scrapy nahezu unbezahlbares Vorwissen vermittelt. ;-)

Ich muß aber auch gestehen, daß ich immer noch kein Freund der 
Dokumentation von BeautifulSoup bin. Viele der für mich wichtigen 
Funktionen fürs Scraping sind erst weiter hinten in der Doku erwähnt, 
"Searching the tree" etwa erst nach gut einem Drittel der Dokumentation 
-- nachdem zuvor langwierig über die manuelle Navigation innerhalb des 
HTML DOM referiert wird. Versteh' mich bitte nicht falsch: ich mag 
BeautifulSoup, aber es hat eben einen ganz anderen Fokus als Scrapy. 
Während Scrapy sich darauf konzentriert, Webseiten herunterzulagen, 
Daten zu extrahieren und sie zu speichern, kann BeautifulSoup beim 
Durchsuchen von HTML-Dokumenten etwa dasselbe wie Scrapy -- aber 
BeautifulSoup kann die HTML-Dokumente eben auch verändern und Teile 
daraus entfernen, hinzufügen oder verändern.

In manchen Fällen kann es daher sogar sinnvoll sein, BeautifulSoup in 
einem Scrapy-Spider einzusetzen, denn in diesem Teilgebiet ist 
BeautifulSoup einfach überlegen. Bei einem meiner Webscraper läuft es 
zum Beispiel so, daß ich einerseits eine von Werbung und anderem 
Schnickschnack befreite Version einer Webseite haben möchte, um sie 
lokal ohne hohe CPU- und Speicherlast meines Browsers lesen zu können. 
Da nutze ich Scrapy für den Download und BeautifulSoup, um ungewollte 
Elemente zu entfernen und die Links der Seiten so umzubiegen, daß sie 
lokal funktionieren. Gleichzeitig ziehe ich mit Scrapy verschiedene 
Datenpunkte aus der Seite, um sie in OpenSearch durchsuchbar 
abzuspeichern und mit OpenSearch Dashboards zu visualisieren, und mit 
scikit-learn und scikit-fuzzy Vorhersagen darüber zu berechnen. Das ist 
in dieser Vielfalt sicher ein seltener Fall, aber er funktioniert prima. 
;-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.