Upload nicht cross-platform?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Crazed
User
Beiträge: 171
Registriert: Sonntag 18. Mai 2008, 11:44

Hallo,
Ich habe mir mittels mechanize relativ einfach 2 Upload scripts für die kostenlose Service SpeedyShare und ImageBanana bauen können.

ImageBanana.py:

Code: Alles auswählen

#!/usr/bin/python
import mechanize
import BeautifulSoup

class ImageBanana(object):
    def __init__(self):
        self.browser = mechanize.Browser()
    
    def upload(self, path):
        data = file(path)
        filename = path.split('/')[-1]
        
        self.browser.open('http://www.imagebanana.com')
        self.browser.select_form(nr=0)
        self.browser.form.add_file(data, filename = filename)
        
        soup = BeautifulSoup.BeautifulSoup(self.browser.submit().read())
        for input in soup.findAll('input'):
            if input['value'].startswith('http://'):
                if input['value'].count('/img/'):
                    return input['value']
SpeedyShare.py:

Code: Alles auswählen

#!/usr/bin/python
import mechanize
import BeautifulSoup

class SpeedyShare(object):
    def __init__(self):
        self.browser = mechanize.Browser()
        self.browser.set_handle_robots(False)
    
    def upload(self, path):
        data = file(path)
        filename = path.split('/')[-1]
        
        self.browser.open('http://www.speedyshare.com/index_upload.php')
        self.browser.select_form(nr=1)
        self.browser.form.add_file(data, filename = filename)
        
        soup = BeautifulSoup.BeautifulSoup(self.browser.submit().read())
        for input in soup.findAll('input'):
            if input['id'] == 'link1':
                return input['value']
Mein Problem ist jetzt, ich weiß nicht genau was das Problem ist :roll: .
Ich bekomme bei ImageBanana einen KeyError und bei SpeedyShare zwar den Link zurück aber die Datei ist fehlerhaft (0 byte). Den Seitenquelltext den ich im ImageBanana.py Modul bekomme mittels:

Code: Alles auswählen

self.browser.submit().read()
Habe ich mir mal genauer angeschaut und gesehen, dass ImageBanana.com eine Error Meldung ausgibt die einfach lautet "Datei konnte nicht hochgeladen werden" o.ä, was IMHO nicht sehr hilfreich ist.

Aber es scheint schon irgendwas mit dem Übertragen der Daten nicht zu stimmen, weil bei SpeedyShare die Dateien ja nachher nur 0 byte groß sind.

Hat jemand eine Idee woran das liegen könnte? Mechanize war doch cross-platform, oder?

MfG,
CracKPod
BlackJack

Der Upload und `mechanize` sollten plattformübergreifend funktionieren. Ich tippe eher auf das öffnen der Datei. Bilder sind Binärdateien und Windows mach da einen Unterschied zwischen Text- und Binärdateien. Da *muss* man die Datei im richtigen Modus öffnen.

Bei Plattformunabhängigkeit fällt das Aufteilen des Pfades ins Auge -- das sollte man mit `os.path.split()` machen.

Ansonsten enthalten die beiden Klassen so viele Gemeinsamkeiten, dass man an das herausziehen einer Basisklasse denken sollte. Ungetestet:

Code: Alles auswählen

import os
import mechanize
import BeautifulSoup


class ImageUploader(object):
    handle_robots = True
    upload_url = None
    form_number = None
    
    def __init__(self):
        self.browser = mechanize.Browser()
        self.browser.set_handle_robots(self.handle_robots)
    
    def _extract_link(self, soup):
        raise NotImplemented
    
    def upload(self, path):
        data = open(path, 'rb')
        filename = os.path.split(path)[-1]
        
        self.browser.open(self.upload_url)
        self.browser.select_form(nr=self.form_number)
        self.browser.form.add_file(data, filename=filename)
        
        soup = BeautifulSoup.BeautifulSoup(self.browser.submit().read())
        return self._extract_link(soup)


class ImageBanana(ImageUploader):
    upload_url = 'http://www.imagebanana.com'
    form_number = 0
    
    def _extract_link(self, soup):
        def check_value(value):
            return value.startswith('http://') and '/img/' in value
        return soup.find('input', {'value': check_value})['value']


class SpeedyShare(ImageUploader):
    handle_robots = False
    upload_url = 'http://www.speedyshare.com/index_upload.php'
    form_number = 1
    
    def _extract_link(self, soup):
        return soup.find('input', id='link1')['value']
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Statt

Code: Alles auswählen

filename = os.path.split(path)[-1]
besser

Code: Alles auswählen

filename = os.path.basename(path)
Müsste

Code: Alles auswählen

raise NotImplemented
nicht besser

Code: Alles auswählen

raise NotImplementedError
heißen?
MfG
HWK
Crazed
User
Beiträge: 171
Registriert: Sonntag 18. Mai 2008, 11:44

Vielen, vielen Dank für die schnelle und hervorragende Hilfe. Ich werde beides gleich austesten!

Crazed
Antworten