Seite 1 von 1

Upload nicht cross-platform?

Verfasst: Freitag 17. Oktober 2008, 23:08
von Crazed
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

Verfasst: Samstag 18. Oktober 2008, 09:23
von 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']

Verfasst: Samstag 18. Oktober 2008, 11:02
von HWK
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

Verfasst: Samstag 18. Oktober 2008, 11:14
von BlackJack
Ja, stimmt (beides).

Verfasst: Samstag 18. Oktober 2008, 13:15
von Crazed
Vielen, vielen Dank für die schnelle und hervorragende Hilfe. Ich werde beides gleich austesten!

Crazed