[gelöst] wget, grep und sed: Turnierdatenbank für Schach

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
garibaldi
Beiträge: 2443
Registriert: 17.09.2004 02:31:12
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

[gelöst] wget, grep und sed: Turnierdatenbank für Schach

Beitrag von garibaldi » 10.06.2015 23:13:48

Hallo allerseits!

Die Schachseite https://www.chess.com speichert alle Partien eines Turniers, von denen man sich auch die *.pgn-Dateien herunterladen kann. Das Summe ist nur, dass dies nur einzeln geht, was natürlich ziemlich umständlich ist. DownThemAll! versagt hier auch seinen Dienst, weil auf der Seite zur Auflistung der Partien (zB. http://www.chess.com/tournaments/games?id=87416 nicht die Direktlinks für die PGNs stehen, sondern man die jeweilige Partie aufrufen muss, um zu dem Link zu kommen.

Also habe ich mich mal mit wget und Konsorten darangesetzt und eine provisorische Lösung gefunden, die ich aber gerne noch vereinfachen möchte.
  1. Erstmal schnappe ich mir die Zeilen aus der Partienseite, die auf die einzelnen Partien verweisen, um die IDs der Partien zu bekommen, und speichere sie in eine Datei:

    Code: Alles auswählen

    wget -O - -o /dev/null http://www.chess.com/tournaments/games?id=87416 | grep echess/game >urigames
  2. Dann schreibe ich die Datei so um, dass ich die entsprechenden Downloadlinks für die Partien erhalte:

    Code: Alles auswählen

    sed 's/^.*game?id/http:\/\/www.chess.com\/echess\/download_pgn?id/;s/"\sid.*$//' urigames >pgnuris
  3. Zum Schluss lade ich die Dateien herunter, wandle die dummen DOS-Zeilenvorschübe um und schreibe alles in eine PGN:

    Code: Alles auswählen

    wget -i pgnuris -O - -o /dev/null | sed 's/.$//' > hotwater1.pgn
Soweit so gut, das ist aber noch ziemlich umständlich, daher wäre ich dankbar für Tipps zur Vereinfachungen des Verfahrens, da kann mir doch sicher jemand weiterhelfen. Außerdem sind die Turnierpartien über mehrere Seiten verteilt, das müsste ich auch noch einbeuziehen, um nicht für jede Seite einzeln diesen Krams machen zu müssen.

Beste Grüße, Gari
Zuletzt geändert von garibaldi am 13.06.2015 20:12:14, insgesamt 1-mal geändert.
Was einer im Reiche der Wahrheit erwirbt, hat er allen erworben... -- Schiller

Benutzeravatar
GregorS
Beiträge: 3133
Registriert: 05.06.2008 09:36:37
Wohnort: Freiburg
Kontaktdaten:

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von GregorS » 10.06.2015 23:37:53

garibaldi hat geschrieben: ... das ist aber noch ziemlich umständlich ...
Wieso ist das umständlich?
... Tipps zur Vereinfachungen des Verfahrens ...
Ich würde das in ein Skript packen. Das kannst Du dann ausführen und musst dafür nur einen einzigen Befehl eingeben.

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen. ("Großes Lötauge", Medizinmann der M3-Hopi [und sog. Maker])

Benutzeravatar
garibaldi
Beiträge: 2443
Registriert: 17.09.2004 02:31:12
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von garibaldi » 10.06.2015 23:58:30

Danke erstmal für die Antwort!
GregorS hat geschrieben:
garibaldi hat geschrieben: ... das ist aber noch ziemlich umständlich ...
Wieso ist das umständlich?
Weil's erstens so noch nicht in ein Script gepackt ist, sondern in einzelne Befehle (;)) und zweitens ich noch das Problem mit den verschiedenen Übersichtsseiten für ein Turnier habe. Dazu habe ich mir gerade curl angesehen, komme damit aber noch nicht klar. :( Es scheitert bei mir schon am laden der Seiten über regex…
GregorS hat geschrieben:
garibaldi hat geschrieben: ... Tipps zur Vereinfachungen des Verfahrens ...
Ich würde das in ein Skript packen. Das kannst Du dann ausführen und musst dafür nur einen einzigen Befehl eingeben.
Hmm ja. Habe ich noch nie gemacht, also erstmal Hilfeseiten blättern. Kennste eine gute für Einsteiger?
Was einer im Reiche der Wahrheit erwirbt, hat er allen erworben... -- Schiller

Cae
Beiträge: 6349
Registriert: 17.07.2011 23:36:39
Wohnort: 2130706433

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von Cae » 10.06.2015 23:59:10

Man kann ausnutzen, dass ungueltige Requests einen HTTP 302 nach /message erzeugen: (110394412 ist ein gueltiger Index, 110394413 nicht)

Code: Alles auswählen

$ wget -Oa --max-redirect=0 -S 'http://www.chess.com/echess/download_pgn?id=110394413'
...
HTTP request sent, awaiting response... 
  HTTP/1.1 302 Found
...
  Location: /message
...
Location: /message [following]
0 redirections exceeded.
$ 
... indem man das Folgen dieser Weiterleitung mit --max-redirect=0 verhindert.

Das scheint ein simpler Index zu sein, den man bruteforcen kann:

Code: Alles auswählen

$ seq 110394412 110394422 | sed 's,^,http://www.chess.com/echess/download_pgn?id=,' | wget --max-redirect=0 -nv -i -
...
$ ls -1
download_pgn?id=110394412
download_pgn?id=110394414
download_pgn?id=110394416
download_pgn?id=110394418
download_pgn?id=110394420
download_pgn?id=110394422
$ 
erzeugt bei mir 6 Datensaetze auf 11 Anfragen. Evtl. sollte man in Zweierschritten inkrementieren.

Natuerlich sind diese Versuche hier nur zu Schulungszwecken dokumentiert und sollten, wenn ueberhaupt, per --limit-rate= oder aehnlichen Verfahren gedrosselt laufen ;).

Gruss Cae
If universal surveillance were the answer, lots of us would have moved to the former East Germany. If surveillance cameras were the answer, camera-happy London, with something like 500,000 of them at a cost of $700 million, would be the safest city on the planet.

—Bruce Schneier

Benutzeravatar
garibaldi
Beiträge: 2443
Registriert: 17.09.2004 02:31:12
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von garibaldi » 11.06.2015 00:17:43

Gehst du gerade davon aus, dass die IDs der Spiele des Turniers in einer sortierten Reihenfolge stehen? Das ist nämlich nicht der Fall. Die Datensätze, die hinterher da sein müssen sind folgende:

Code: Alles auswählen

guybrush@marvin:~/tmp/wget$ wget -O - -o /dev/null http://www.chess.com/tournaments/games?id=87416 | grep echess/game >urigames
guybrush@marvin:~/tmp/wget$ sed 's/^.*game?id/http:\/\/www.chess.com\/echess\/download_pgn?id/;s/"\sid.*$//' urigames >pgnuris
guybrush@marvin:~/tmp/wget$ cat pgnuris 
http://www.chess.com/echess/download_pgn?id=111277688
http://www.chess.com/echess/download_pgn?id=111431196
http://www.chess.com/echess/download_pgn?id=111309034
http://www.chess.com/echess/download_pgn?id=110937568
http://www.chess.com/echess/download_pgn?id=110394418
http://www.chess.com/echess/download_pgn?id=110944492
http://www.chess.com/echess/download_pgn?id=110394412
http://www.chess.com/echess/download_pgn?id=110394416
http://www.chess.com/echess/download_pgn?id=110394410
http://www.chess.com/echess/download_pgn?id=110394420
http://www.chess.com/echess/download_pgn?id=110581478
http://www.chess.com/echess/download_pgn?id=110394414
http://www.chess.com/echess/download_pgn?id=107381428
http://www.chess.com/echess/download_pgn?id=107425384
http://www.chess.com/echess/download_pgn?id=106692820
http://www.chess.com/echess/download_pgn?id=105373804
http://www.chess.com/echess/download_pgn?id=105715604
http://www.chess.com/echess/download_pgn?id=106801266
http://www.chess.com/echess/download_pgn?id=106547162
http://www.chess.com/echess/download_pgn?id=106722810
http://www.chess.com/echess/download_pgn?id=103638896
http://www.chess.com/echess/download_pgn?id=103638908
http://www.chess.com/echess/download_pgn?id=104700154
http://www.chess.com/echess/download_pgn?id=105547778
http://www.chess.com/echess/download_pgn?id=105657602
http://www.chess.com/echess/download_pgn?id=105484020
http://www.chess.com/echess/download_pgn?id=103638926
http://www.chess.com/echess/download_pgn?id=103638924
http://www.chess.com/echess/download_pgn?id=103638900
http://www.chess.com/echess/download_pgn?id=104462788
http://www.chess.com/echess/download_pgn?id=103638902
http://www.chess.com/echess/download_pgn?id=104774206
http://www.chess.com/echess/download_pgn?id=105064160
http://www.chess.com/echess/download_pgn?id=104774158
http://www.chess.com/echess/download_pgn?id=105169112
http://www.chess.com/echess/download_pgn?id=105077282
http://www.chess.com/echess/download_pgn?id=104824738
http://www.chess.com/echess/download_pgn?id=105202986
http://www.chess.com/echess/download_pgn?id=103638934
http://www.chess.com/echess/download_pgn?id=103638922
http://www.chess.com/echess/download_pgn?id=104452912
http://www.chess.com/echess/download_pgn?id=103638936
http://www.chess.com/echess/download_pgn?id=103638938
http://www.chess.com/echess/download_pgn?id=103638914
http://www.chess.com/echess/download_pgn?id=104328814
http://www.chess.com/echess/download_pgn?id=103638942
http://www.chess.com/echess/download_pgn?id=103638916
http://www.chess.com/echess/download_pgn?id=103638910
http://www.chess.com/echess/download_pgn?id=103638894
http://www.chess.com/echess/download_pgn?id=104416208
Ansonsten habe ich, ganz ehrlich, nicht kapiert, was du da machst… 8O


-----------------------------------------------------------------------------------------

Edit: Script für eine Seite

So weit bin ich schon einmal:
(Bitte nicht Auslachen, ist mein erstes Script!)

Code: Alles auswählen

#!/bin/bash
# 
# tournget.sh
# script for downloading multiple tournament *.png from chess.com
#

echo "Script for downloading multiple tournament *.png files from chess.com"

if [ -n "$1" ]
	then
		wget -O - -o /dev/null http://www.chess.com/tournaments/games?id="$1" | grep echess/game >/tmp/urigames
	else
		echo "usage: tournget.sh GAMES_ID OUTPUT[.PGN]"
fi

if [ -f /tmp/urigames ]
	then
		sed 's/^.*game?id/http:\/\/www.chess.com\/echess\/download_pgn?id/;s/"\sid.*$//' /tmp/urigames >/tmp/pgnuris
	else
		echo "Error while reading games ID!"
fi

if [ -f /tmp/pgnuris ]
	then
		echo "Compiling $2.pgn. Please wait..."
		wget -i /tmp/pgnuris -O - -o /dev/null | sed 's/.$//' > $2.pgn
	else
		echo "Error while compiling PGN file!"
fi

rm -v /tmp/urigames /tmp/pgnuris

echo "$2.pgn is ready to use! :)"
Verbesserungsvorschläge sind mir selbstverständlich sehr willkommen! :)

Es fehlt hier halt noch das Hinzufügen der PGNs der folgenden Seiten vom Turnier…
Was einer im Reiche der Wahrheit erwirbt, hat er allen erworben... -- Schiller

Benutzeravatar
garibaldi
Beiträge: 2443
Registriert: 17.09.2004 02:31:12
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von garibaldi » 11.06.2015 05:00:49

So klappt es, aber man muss dabei noch die Seitenanzahl manuell eingeben. Kann man das nicht auch noch automatisieren?

Code: Alles auswählen

~void~
Edit

Das Script habe ich noch etwas überarbeitet und es daher nach Nopaste geschoben: NoPaste-Eintrag38588

Eine Frage habe ich noch zur Verwendung von read -n 1 char, siehe Zeile 37ff. Der Abruf tut prinzipiell schon, was er soll, aber wenn man hier zum Forfahren "o" eingibt, wird der Buchstabe beim nächsten echo mit ausgegeben, befindet sich also immer noch im Puffer. Kann man das irgendwie wegkriegen?

Lässt sich zudem die Abfrage auch so einstellen, dass Groß-/Kleinschreibung ignoriert wird?
Was einer im Reiche der Wahrheit erwirbt, hat er allen erworben... -- Schiller

linuxCowboy
Beiträge: 287
Registriert: 05.02.2013 19:47:41

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von linuxCowboy » 12.06.2015 02:00:17

garibaldi hat geschrieben:Eine Frage habe ich noch zur Verwendung von read -n 1 char, ... wenn man hier zum Forfahren "o" eingibt, wird der Buchstabe beim nächsten echo mit ausgegeben, ... Kann man das irgendwie wegkriegen?
read -sn1 char
garibaldi hat geschrieben:Lässt sich zudem die Abfrage auch so einstellen, dass Groß-/Kleinschreibung ignoriert wird?
if echo $char | grep -iq 'o';then echo o_or_O;else echo abort;fi
-der_linux_cowboy --- Besser werden! ... f*** w$$

Benutzeravatar
garibaldi
Beiträge: 2443
Registriert: 17.09.2004 02:31:12
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Berlin

Re: wget, grep und sed: Turnierdatenbank für Schach

Beitrag von garibaldi » 13.06.2015 20:11:45

Vielen Dank, linuxCowboy!

So funktioniert der Abruf mit read wie gewünscht. :)

Zum anderen Problem: Es ist wohl nicht so trivial zu lösen, den Abruf der Seiten mit den Partien zu automatisieren. Grund dafür ist, dass die Seite keine Fehlermeldung gibt, wenn man eine nicht existierende Seite aufruft, sondern wieder zurück auf Seite 1 springt. Da müsste amn wahrscheinlich mit diff oder so kontrollieren, ob neue Partien geladen werden oder bereits existierende. Ist mir aber jetzt zu kompliziert, also setze ich das hier mal auf "gelöst".

Vielen Dank nochmal für eure Hinweise!
Was einer im Reiche der Wahrheit erwirbt, hat er allen erworben... -- Schiller

linuxCowboy
Beiträge: 287
Registriert: 05.02.2013 19:47:41

Re: [gelöst] wget, grep und sed: Turnierdatenbank für Schach

Beitrag von linuxCowboy » 14.06.2015 16:54:39

Mach doch einfach den Sack zu:

Code: Alles auswählen

#!/bin/bash

FILE=PGNs

rm -f $FILE

ids=$(
for i in {1..7};do
	wget -nv -O- "http://www.chess.com/tournaments/games?id=87416&page=$i" |
		perl -nE 'say $1 if m%echess/game\?id=(\d+)%'
done)

printf "\n %d Games\n\n" `echo $ids | wc -w`

for i in $ids;do
	wget -nv -O- "http://www.chess.com/echess/download_pgn?id=$i"
	echo -----
done >>$FILE
Syntax: NoPaste-Eintrag38592
-der_linux_cowboy --- Besser werden! ... f*** w$$

Antworten