Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Kleines Downloadskript

4 views
Skip to first unread message

Richard llom

unread,
Apr 16, 2013, 5:40:48 PM4/16/13
to
Hallo,
will mir ein kleine Skript schreiben welches eine URL aus einer Seite (aus
dem Quelltext) ausliest und das Ziel dieser URL dann auf der Festplatte
speichert. Die Quellseiten (so ca. 8-12 jeweils) werde ich vorher von Hand
in eine Textdatei schreiben.
Was ich schon herausgefunden habe:
mit
wget -i seiten.txt -O seiten.html
bekomme ich den Quelltext aller Seiten in "seiten.html"
mit
grep "regexp" seiten.html > downloads.txt
sollten alle Download-Urls in downloads.txt stehen.

Hier habe ich aber noch ein paar Probleme.
Der relevante Quelltext sieht so aus:
...
//addVar("file","URL");
addVar("file","URL");
..
mit grep addVar\(\"file\",\".*\" seiten.html > downloads.txt
bekomme ich aber immer nur die kompletten Zeilen?
Außerdem wie muss ich die regExp verändern um den auskommentierten Teil
(//...) auszuschließen? (übrigens der Grund warum meine bisherige Lösung
nicht mehr funktioniert)

Und welches cli-tool kann ich schließlich benutzen um die Ziele der URL
herunterzuladen? Am liebsten eins mit Geschwindigkeit- und
Fortschrittsanzeige (wie bei pacman z.Bsp.).

Danke schon mal
richard
Message has been deleted

Thomas 'PointedEars' Lahn

unread,
Apr 18, 2013, 2:56:09 PM4/18/13
to
Richard llom wrote:

> will mir ein kleine Skript schreiben welches eine URL aus einer Seite (aus
> dem Quelltext) ausliest und das Ziel dieser URL dann auf der Festplatte
> speichert. Die Quellseiten (so ca. 8-12 jeweils) werde ich vorher von Hand
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> in eine Textdatei schreiben.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Wie bitte?

> Was ich schon herausgefunden habe:
> mit
> wget -i seiten.txt -O seiten.html
> bekomme ich den Quelltext aller Seiten in "seiten.html"
> mit
> grep "regexp" seiten.html > downloads.txt
> sollten alle Download-Urls in downloads.txt stehen.
>
> Hier habe ich aber noch ein paar Probleme.
> […]
> Außerdem wie muss ich die regExp verändern um den auskommentierten Teil
> (//...) auszuschließen? (übrigens der Grund warum meine bisherige Lösung
> nicht mehr funktioniert)

HTML mit regulären Ausdrücken *ohne Kontext* parsen zu wollen ist ein
häufiger Anfängerfehler. Gültiges HTML 4.01 Strict ist isomorph zur Sprache
korrekter Klammerausdrücke (“<div><p>…</p></div><div>…</div>” ≡ “((…))(…)”);
somit eine kontextfreie, *nicht-reguläre* (Chomsky-Typ-2-)Sprache. Leider
ist nicht einmal jedes HTML-Dokument auch gültiges HTML 4.01 Strict.
Fortgeschrittene bauen sich dafür einen effizienten, PDA-basierten Parser.

Das vermutlich Einfachste mit Bordmitteln ist, grep(1) auf die Ausgabe von
“lynx -dump "$URI"” loszulassen; diese enthält am Ende wirklich *nur* die
URIs.

> Und welches cli-tool kann ich schließlich benutzen um die Ziele der URL
> herunterzuladen? Am liebsten eins mit Geschwindigkeit- und
> Fortschrittsanzeige (wie bei pacman z.Bsp.).

wget(1) kann man mit einer Datei füttern, die eine Liste mit URIs enthält.
curl(1) auch.

Allerdings können wget(1) und curl(1) auch selbstständig und *viel besser*
die URIs aus einem Online-HTML-Dokument extrahieren, denn dafür wurden sie
entwickelt. Dein „Downloadskript“ besteht somit wahrscheinlich nur aus
einer Zeile. RTFM.

--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

unread,
Apr 18, 2013, 2:57:44 PM4/18/13
to
Frank Graf wrote:

> Am Tue, 16 Apr 2013 23:40:48 +0200 schrieb Richard llom:
> [...]
>> Hier habe ich aber noch ein paar Probleme.
>> Der relevante Quelltext sieht so aus:
>> ...
>> //addVar("file","URL");
>> addVar("file","URL");
>> ..
>> mit grep addVar\(\"file\",\".*\" seiten.html > downloads.txt bekomme ich
>> aber immer nur die kompletten Zeilen?
>
> grep gibt immer ganze Zeilen aus. Mit dem Tool awk sollte das Problem
> lösbar sein.

Wenn überhaupt, dann nur sehr mühevoll. Siehe andere Antwort.

Richard llom

unread,
Apr 28, 2013, 6:35:21 PM4/28/13
to
Thomas 'PointedEars' Lahn wrote:
> Richard llom wrote:
>> will mir ein kleine Skript schreiben welches eine URL aus einer Seite
>> (aus dem Quelltext) ausliest und das Ziel dieser URL dann auf der
>> Festplatte speichert. Die Quellseiten (so ca. 8-12 jeweils) werde ich
>> vorher von Hand
>> in eine Textdatei schreiben.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> Wie bitte?
>
Mit Quellseiten meinte ich die URLs, also
www.test.org/test1.html, etc.

>> Was ich schon herausgefunden habe:
>> mit
>> wget -i seiten.txt -O seiten.html
>> bekomme ich den Quelltext aller Seiten in "seiten.html"
>> mit
>> grep "regexp" seiten.html > downloads.txt
>> sollten alle Download-Urls in downloads.txt stehen.
>>
> HTML mit regulären Ausdrücken *ohne Kontext* parsen zu wollen ist ein
> häufiger Anfängerfehler.
>
Problem ist, es gibt eben diesen Kontext nicht. Die gesuchte URI ist kein
Link in der Seite und auch sonst nicht mit HTML-tags o.ä. versehen (s. Bsp.
im OP).

> Das vermutlich Einfachste mit Bordmitteln ist, grep(1) auf die Ausgabe von
> “lynx -dump "$URI"” loszulassen; diese enthält am Ende wirklich *nur* die
> URIs.
>
Das liefert die gesuchte URI nicht (s.o.).

> Allerdings können wget(1) und curl(1) auch selbstständig und *viel besser*
> die URIs aus einem Online-HTML-Dokument extrahieren, denn dafür wurden sie
> entwickelt. Dein „Downloadskript“ besteht somit wahrscheinlich nur aus
> einer Zeile. RTFM.
>
Hab ich (inzwischen) getan, aber auch hier sehe ich keine Möglichkeit
beliebige URI aus dem Quelltext der Seite auszulesen. wget --accept-
regex="regex" ... tut es nicht.

Thomas 'PointedEars' Lahn

unread,
Apr 29, 2013, 2:02:49 PM4/29/13
to
Richard llom wrote:

> Thomas 'PointedEars' Lahn wrote:
>> Richard llom wrote:
>>> will mir ein kleine Skript schreiben welches eine URL aus einer Seite
>>> (aus dem Quelltext) ausliest und das Ziel dieser URL dann auf der
>>> Festplatte speichert. Die Quellseiten (so ca. 8-12 jeweils) werde ich
>>> vorher von Hand
>>> in eine Textdatei schreiben.
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> Wie bitte?
>
> Mit Quellseiten meinte ich die URLs, also
> www.test.org/test1.html, etc.

ACK. Es wäre wirklich sinnvoll, wenn Du Dich korrekter Terminologie
bedientest. Unter „(Quell)seiten“ werden üblicherweise (HTML)-Dokumente
verstanden. URLs bzw. URIs haben jedoch mit HTML nicht unbedingt etwas zu
tun.

>>> Was ich schon herausgefunden habe:
>>> mit
>>> wget -i seiten.txt -O seiten.html
>>> bekomme ich den Quelltext aller Seiten in "seiten.html"
>>> mit
>>> grep "regexp" seiten.html > downloads.txt
>>> sollten alle Download-Urls in downloads.txt stehen.
>>>
>> HTML mit regulären Ausdrücken *ohne Kontext* parsen zu wollen ist ein
>> häufiger Anfängerfehler.
>
> Problem ist, es gibt eben diesen Kontext nicht. Die gesuchte URI ist kein
> Link in der Seite und auch sonst nicht mit HTML-tags o.ä. versehen (s.
> Bsp. im OP).

Es geht also gar nicht um HTML, sondern um URIs. Das ging für mich aus
Deinem OP nicht hervor. Du solltest das nächste Mal besser versteh- und
lesbar posten. Hier wäre zum Beispiel der Gebrauch korrekter Terminologie
und ab und zu ein Absatz für den Leser hilfreich gewesen.

>> Das vermutlich Einfachste mit Bordmitteln ist, grep(1) auf die Ausgabe
>> von “lynx -dump "$URI"” loszulassen; diese enthält am Ende wirklich *nur*
>> die URIs.
>
> Das liefert die gesuchte URI nicht (s.o.).

Richtig, fhcsal/ungenaue Fragen führen zu afhsclen Antworten. Du suchst
URIs und musst also den regulären Ausdruck für URIs auf Deine Texte
anwenden. Du findest einen grep-kompatiblen Ansatz dafür in Anhang B von
RFC 3986.

grep(1) wäre dann theoretisch eher in de.comp.os.unix.shell on-topic. (Der
Nachteil einer Baumstruktur ist leider, dass es manchmal keine eindeutige
Zuordnung eines Themas zu einem Knoten gibt – das hatte ironischerweise
bereits Tim Berners-Lee in seinem ersten WWW-Vorschlag ans CERN erkannt.)

>> Allerdings können wget(1) und curl(1) auch selbstständig und *viel
>> besser* die URIs aus einem Online-HTML-Dokument extrahieren, denn dafür
>> wurden sie entwickelt. Dein „Downloadskript“ besteht somit
>> wahrscheinlich nur aus einer Zeile. RTFM.
>
> Hab ich (inzwischen) getan, aber auch hier sehe ich keine Möglichkeit
> beliebige URI aus dem Quelltext der Seite auszulesen. wget --accept-
> regex="regex" ... tut es nicht.

Stimmt, zumindest *w*get ist für die Verarbeitung von *Web*dokumenten und
Verfolgen von Links darin (Spider) entwickelt worden. Da es sich nicht um
Links handelt, funktioniert das so nicht. Aber was passiert, wenn Du die
Textdatei als Eingabedatei (Linkliste) für wget verwendest (“-i”)?

Bei curl(1) weiss ich es nicht – der Name deutet zumindest an, dass es damit
bequemer als mit “wget -i <(grep …)” gehen *könnte* (ich habe damit bisher
immer nur direkt heruntergeladen). RTFM.

Helmut Hullen

unread,
Apr 29, 2013, 2:16:00 PM4/29/13
to
Hallo, Thomas,

Du meintest am 29.04.13:

>> Mit Quellseiten meinte ich die URLs, also
>> www.test.org/test1.html, etc.

> ACK. Es w�re wirklich sinnvoll, wenn Du Dich korrekter Terminologie
> bedientest.

Lass mich raten: Du arbeitest im Verkauf und darfst dort die Kundschaft
erziehen?

Viele Gruesse
Helmut

"Ubuntu" - an African word, meaning "Slackware is too hard for me".

Christoph Federer

unread,
May 29, 2013, 6:09:26 PM5/29/13
to
Hallo,

Frank Graf schrieb:

> Hallo,
>
> Am Tue, 16 Apr 2013 23:40:48 +0200 schrieb Richard llom:
>
> [...]
>
>> Hier habe ich aber noch ein paar Probleme.
>> Der relevante Quelltext sieht so aus:
>> ...
>> //addVar("file","URL");
>> addVar("file","URL");
>> ..
>> mit grep addVar\(\"file\",\".*\" seiten.html > downloads.txt bekomme ich
>> aber immer nur die kompletten Zeilen?
>
> grep gibt immer ganze Zeilen aus. Mit dem Tool awk sollte das Problem
> lösbar sein.

Das stimmt so nicht. Mit dem Parameter -o wird nur der Teil ausgegeben, auf
den das Pattern passt.

>
>> Außerdem wie muss ich die regExp verändern um den auskommentierten Teil
>> (//...) auszuschließen? (übrigens der Grund warum meine bisherige Lösung
>> nicht mehr funktioniert)
Am einfachsten ist wohl eine Kaskade von grep und sed:
grep -o /*addVar\(\"file\",\".*\"\) seiten.html|
grep -v //addVar|
grep -o \,\".*\"|
sed -e s/\,\"//g -e s/\"//g |
while read line; do wget $line; done

Zeile 1 siebt kommentierte und nicht kommentierte Statements heraus, Zeile 2
filtert die kommentierten raus, Zeile 3 extrahiert den URL, Z4 löscht noch
störende Zeichen und Z5 verfüttert das ganze zum Schluss direkt an wget.


>>
>> Und welches cli-tool kann ich schließlich benutzen um die Ziele der URL
>> herunterzuladen? Am liebsten eins mit Geschwindigkeit- und
>> Fortschrittsanzeige (wie bei pacman z.Bsp.).
>
> wget zeigt den Fortschritt an, siehe in der man page die Angaben zum
> Parameter "--progress":
>
> --progress=type
>
>
>
> Frank

Gruß
Christoph

Thomas 'PointedEars' Lahn

unread,
Jun 26, 2013, 7:23:10 AM6/26/13
to
[X-Post & F'up2 de.comp.os.unix.shell; <http://www.liesmal.de/fup2-faq>]

Christoph Federer wrote in de.comp.os.unix.apps.misc:

> Frank Graf schrieb:
>> Am Tue, 16 Apr 2013 23:40:48 +0200 schrieb Richard llom:
>> [...]
>>> Hier habe ich aber noch ein paar Probleme.
>>> Der relevante Quelltext sieht so aus:
>>> ...
>>> //addVar("file","URL");
>>> addVar("file","URL");
>>> ..
>>> mit grep addVar\(\"file\",\".*\" seiten.html > downloads.txt bekomme ich
>>> aber immer nur die kompletten Zeilen?
>>
>> grep gibt immer ganze Zeilen aus. Mit dem Tool awk sollte das Problem
>> lösbar sein.
>
> Das stimmt so nicht. Mit dem Parameter -o wird nur der Teil ausgegeben,
> auf den das Pattern passt.

ACK.

>>> Außerdem wie muss ich die regExp verändern um den auskommentierten Teil
>>> (//...) auszuschließen? (übrigens der Grund warum meine bisherige Lösung
>>> nicht mehr funktioniert)
> Am einfachsten ist wohl eine Kaskade von grep und sed:
> grep -o /*addVar\(\"file\",\".*\"\) seiten.html|
> grep -v //addVar|
> grep -o \,\".*\"|
> sed -e s/\,\"//g -e s/\"//g |
> while read line; do wget $line; done
>
> Zeile 1 siebt kommentierte und nicht kommentierte Statements heraus, Zeile
> 2 filtert die kommentierten raus, Zeile 3 extrahiert den URL, Z4 löscht
> noch störende Zeichen und Z5 verfüttert das ganze zum Schluss direkt an
> wget.

Das ist

0. fhcsal, denn Anweisungen funktionieren nicht mit einer *beliebigen*
Anzahl führender “/”;

1. ineffizient, denn
a. viele Escape-Sequenzen sind überflüssig;
b. Kommentarzeilen lassen sich von vornherein ausschliessen;
c. sed(1) kann die Filterung selbst;
d. wget(1) kann die zeilenweise Verarbeitung selbst;

2. fehlerträchtig, weil Du davon ausgehst, dass
a. in jeder Zeile nur eine Anweisung steht, dem kein Kommentar folgt;
b. „addVar“ unmittelbar auf den Kommentar folgen muss;
c. ein Kommentar immer „addVar“ enthalten muss;
d. „"“ unmittelbar auf das Komma folgen muss;
e. der Programmierer immer einen nicht-leeren Wert angegeben hat;
f. der Programmierer nicht vergessen hat, Leerzeichen zu maskieren;
g. kein „\“ enthalten ist, der “read” durcheinanderbringen könnte.

zu 0, 1a, 1b, 1d, und 2b bis 2g:

grep -o '^[[:space:]]*addVar[[:space:]]*([[:space:]]*"file"[[:space:]]*,\
[[:space:]]*"[^"]\{1,\}"[[:space:]]*)' seiten.html |
grep -o ',[[:space:]]*"[^ "]\{1,\}"' |
sed -e 's/,"//g; s/"//g' |
wget -i -

zu 1c:

expr='^[[:space:]]*addVar[[:space:]]*([[:space:]]*"file"[[:space:]]*,\
[[:space:]]*"\([^"]\{1,\}\)"[[:space:]]*)[[:space]]*;'
sed -ne "$expr { s/$expr/\\1/; p }" seiten.html | \
wget -i -

Etwas schöner geht es natürlich mit GNU sed –

expr='^[[:space:]]*addVar[[:space:]]*([[:space:]]*"file"[[:space:]]*,\
[[:space:]]*"\(\([^"\\]\|\\.\)+\)"[[:space:]]*)[[:space]]*;'
sed -nre "/$expr/ { s/$expr/\\1/; p }" seiten.html \
wget -i -

– und deutlich schöner mit Perl:

perl -ne '
m{^\s*addVar\s*\(\s*"file"\s*,\s*"((?:[^\\"]|\\.)+)"\s*\)\s*;} &&
print $1 . "\n";' < seiten.html |
wget -i -


Bitte nur das Wesentliche zitieren:
<http://lernst.de/zitieren/kriegst.de/antworten>
0 new messages