2011-01-03 17 views
3

Mit Urllib2 können wir die HTTP-Antwort von einem Webserver abrufen. Wenn dieser Server einfach eine Liste von Dateien enthält, können wir die Dateien analysieren und einzeln herunterladen. Ich bin mir jedoch nicht sicher, was der einfachste, pythischste Weg wäre, die Dateien zu analysieren.Herunterladen von Dateien von einem HTTP-Server in Python

Wenn Sie eine vollständige HTTP-Antwort der generischen Dateiserverliste durch urlopen() - Methode von urllib2 erhalten, wie können wir jede Datei sauber herunterladen?

+0

Möchten Sie uns drei oder vier Zeilen Beispielquelle aus dieser "Liste der Dateien" geben, damit wir sehen können, welche Art von zusätzlicher Formatierung beteiligt sein könnte? –

Antwort

3

Können Sie garantieren, dass die von Ihnen angeforderte URL eine Verzeichnisliste ist? Wenn ja, können Sie das Format der Verzeichnisliste garantieren?

Wenn ja, könnten Sie lxml verwenden, um das zurückgegebene Dokument zu analysieren und alle Elemente zu finden, die den Pfad zu einer Datei enthalten, dann über diese Elemente iterieren und jede Datei herunterladen.

+3

+1. Manche Leute benutzen lieber Beautiful Soup statt Lxml. –

+1

Und einige noch gerne Pyquery verwenden;) –

2

Hier ist eine nicht getestete Lösung:

import urllib2 

response = urllib2.urlopen('http://server.com/file.txt') 
urls = response.read().replace('\r', '').split('\n') 

for file in urls: 
    print 'Downloading ' + file 

    response = urllib2.urlopen(file) 

    handle = open(file, 'w') 
    handle.write(response.read()) 
    handle.close() 

Es ist nicht getestet, und es wird wahrscheinlich nicht funktionieren. Dies setzt voraus, dass Sie eine tatsächliche Liste von Dateien innerhalb einer anderen Datei haben. Viel Glück!

9

Urllib2 ist möglicherweise OK, um die Liste der Dateien abzurufen. Zum Herunterladen großer Mengen von Binärdateien ist PycURL http://pycurl.sourceforge.net/ eine bessere Wahl. Dies funktioniert für meine IIS basierten Dateiserver:

import re 
import urllib2 
import pycurl 

url = "http://server.domain/" 
path = "path/" 
pattern = '<A HREF="/%s.*?">(.*?)</A>' % path 

response = urllib2.urlopen(url+path).read() 

for filename in re.findall(pattern, response): 
    fp = open(filename, "wb") 
    curl = pycurl.Curl() 
    curl.setopt(pycurl.URL, url+path+filename) 
    curl.setopt(pycurl.WRITEDATA, fp) 
    curl.perform() 
    curl.close() 
    fp.close() 
+0

Ich habe keine Geschwindigkeit Tests, aber es ist auch möglich, 'BeautifulSoup' zu verwenden, um alle' 's und dann' .text' von ihnen zu bekommen. – boldnik

2
  1. den Datei-Index Herunterladen

    Wenn es wirklich riesig, es kann sich lohnen, ein Stück zu einer Zeit, zu lesen; sonst ist es wahrscheinlich einfacher, einfach das Ganze in den Speicher zu packen.

  2. Auszug der Liste der Dateien

    zu bekommen Wenn die Liste XML oder HTML ist, einen geeigneten Parser verwenden; sonst, wenn es viel String-Verarbeitung zu tun gibt, verwenden Sie Regex; sonst verwenden Sie einfache String-Methoden.

    Auch hier können Sie alles auf einmal oder inkrementell parsen. Inkrementell ist etwas effizienter und elegant, aber wenn Sie mehrere Zehntausende von Zeilen verarbeiten, ist es wahrscheinlich nicht kritisch.

  3. Laden Sie sie für jede Datei herunter und speichern Sie sie in einer Datei.

    Wenn Sie versuchen, die Dinge zu beschleunigen, können Sie versuchen, mehrere Download-Threads ausführen;

    andere (deutlich schneller) Ansatz könnte sein, um die Arbeit zu einem dedizierten Downloader Programm zu delegieren wie aria2 http://aria2.sourceforge.net/ - beachten Sie, dass aria2 als Dienst ausgeführt werden kann und über XMLRPC gesteuert, siehe http://sourceforge.net/apps/trac/aria2/wiki/XmlrpcInterface#InteractWitharia2UsingPython

2

Mein Vorschlag wäre, BeautifulSoup (das ist ein HTML/XML-Parser) zu verwenden, um die Seite für eine Liste von Dateien zu analysieren. Dann würde pycURL definitiv nützlich sein.

Eine andere Methode, nachdem Sie die Liste der Dateien haben, ist die Verwendung von urllib.urlretrieve in einer ähnlichen Weise wie wget, um die Datei einfach an einen Speicherort auf Ihrem Dateisystem herunterzuladen.

4

können Sie urllib.urlretrieve verwenden (in Python 3.x: urllib.request.urlretrieve):

import urllib 
urllib.urlretrieve('http://site.com/', filename='filez.txt') 

Diese Arbeit sollte :)

und dies ist ein fnction, dass das tun kann, gleiche (mit urllib):

def download(url): 
    webFile = urllib.urlopen(url) 
    localFile = open(url.split('/')[-1], 'w') 
    localFile.write(webFile.read()) 
    webFile.close() 
    localFile.close() 
2

Dies ist eine nicht-convential Art und Weise ist, aber obwohl es funktioniert

fPointer = open(picName, 'wb') 
self.curl.setopt(self.curl.WRITEFUNCTION, fPointer.write) 


urllib.urlretrieve(link, picName) - correct way 
Verwandte Themen