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...
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.
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...
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? ..
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...
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?
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()
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.
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.
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.
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.
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.
;-)