[Python] Chomikuj.pl - bot do uploadowania

Witam,

Chciałem napisać sobie program do wysyłania plików na serwis chomikuj.pl .

Staram się, żeby program wysyłał mniej, więcej takie same pakiety http, jak przeglądarka.

Nie wiem jednak co robię źle, bo w ostateczności plik nie zostaje umieszczony na serwerze.

#!/usr/bin/env python 

# -*- coding: utf-8 -*- 


import urllib2, urllib

import ClientForm

import random

import re

import socket

import cookielib

import httplib


#ChomikID, ChomikSubfolderId, SubfolderId, UploadToken, TokenTime

httpdata = """ctl00%24SM=ctl00%24CT%24NewFolder%24NFUp%7Cctl00%24CT%24NewFolder%24NewFolderButton&PageCmd=&PageArg=undefined&ctl00%24SearchInputBox=&ctl00%24SearchFileBox=&ctl00%24SearchType=all&SType=0&ctl00%24CT%24ChomikID={0}&ctl00%24CT%24TW%24TreeExpandLog=20188%7C&ChomikSubfolderId={1}&ctl00%24CT%24FW%24SubfolderID={2}&ctl00%24CT%24FW%24UploadToken={3}&ctl00%24CT%24FW%24TokenTime={4}&FVSortType=1&FVSortDir=1&FVSortChange=&FVPage=0&ctl00%24CT%24FrW%24FrPage=1&FrGroupId=0&FrRefPage=&FrGrpPage=&FrGrpName=&ctl00%24CT%24NewFolder%24NewFolderTextBox={5}&ctl00%24CT%24NewFolder%24AFDescr=&ctl00%24CT%24NewFolder%24AFPass=& __EVENTTARGET=ctl00%24CT%24NewFolder%24NewFolderButton&__ EVENTARGUMENT=& __VIEWSTATE=%2FwEPDwUKMTc2NzM2Njg0MxBkZBYCZg9kFgICAQ8WAh4GYWN0aW9uBQgvYWRhbV9nchYCAhUPZBYCAjMPZBYCZg9kFgICAw9kFgJmD2QWAgICD2QWAgIBD2QWAgIBD2QWAmYPZBYCAgMPZBYEZg9kFgQCAQ8PZA8QFgJmAgEWAhYCHg5QYXJhbWV0ZXJWYWx1ZQUFMjAxODgWAh8BZRYCZmZkZAIJDxQrAAJkZGQCAQ9kFgQCAQ8PZA8QFgJmAgEWAhYCHwEFBTIwMTg4FgIfAWUWAmZmZGQCCA8UKwACZGRkGAUFGWN0bDAwJENUJE1zZ0MkUE1TZW50UGFnZXIPFCsABGRkAhRmZAUUY3RsMDAkQ1QkTXNnQyRQTVNlbnQPPCsACgEGFQECaWRkBRZjdGwwMCRDVCRNc2dDJE1MTFBhZ2VyDxQrAARkZAIUZmQFEWN0bDAwJENUJE1zZ0MkTUxMDzwrAAoBBhUBAmlkZAUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgUFHGN0bDAwJExvZ2luVG9wJExvZ2luUmVtZW1iZXIFGmN0bDAwJExvZ2luVG9wJExvZ2luQnV0dG9uBRtjdGwwMCRDVCRQZXJtVyRMb2dpbkN0cmwkUkIFIGN0bDAwJENUJE5ld0ZvbGRlciROZXdGb2xkZXJNb2RlBSFjdGwwMCRDVCROZXdGb2xkZXIkTmV3Rm9sZGVyQWR1bHQ%3D&__ ASYNCPOST=true&"""



class Chomik(object):

    def __init__ (self):

        self.opener  = urllib2.build_opener()

        #obecna pozycja wsrod katalogow

        self.cur_adr = 'http://chomikuj.pl'


        

    def login(self, user, password):

        """

        Logowanie sie do chomika

        """

        #Wlaczenie trybu debuggowania (wyswietlanie wysylanych i otrzymywanych pakietow)

        h         = urllib2.HTTPHandler(debuglevel=1)

        #obsluga ciasteczek

        jar       = cookielib.CookieJar()

        opener    =  urllib2.build_opener(h, urllib2.HTTPCookieProcessor(jar))

        #Przedstawiajmy sie jakos ladnie

        opener.addheaders = [('User-Agent','Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')]

        

        #print "Logowanie"

        login_url = "http://chomikuj.pl"

        request   = urllib2.Request(login_url)

        response  = opener.open(request)

        #Przeparsujmy strone w celu znalezienia formularzy

        forms     = ClientForm.ParseResponse(response,backwards_compat=False)

        response.close()

        #wybieramy pierwszy formularz

        form = forms[0]

        #i wypelniamy go

        form['ctl00$LoginTop$LoginChomikName']     = user

        form['ctl00$LoginTop$LoginChomikPassword'] = password

        form['ctl00$LoginTop$LoginRemember']       = ['on']

        request   = form.click('ctl00$LoginTop$LoginButton')

        response  = opener.open(request)

        

        url  = response.geturl()

        response.close()

        

        self.opener  = opener

        self.cur_adr = url


    

    

    def chdirs(self, directories):

        """

        Zmien katalog

        np. (chdirs(/katalog1/katalog2/katalog3) )

        """

        dirs = [i for i in directories.split('/') if i != '']

        for dir in dirs:

            self.chdir(dir.replace('/',''))

        

    

    

    def chdir(self, directory):

        """

        Zmien katalog (zmiana o jeden poziom)

        """

        if directory == '..':

            #wyjdz z katalogu

            self.cur_adr,_,_ = self.cur_adr.rpartition('/')

            return

        wzor      = '(]*>(]*>)?([^<]*))'

        aut       = re.compile(wzor)

        

        request   = urllib2.Request(self.cur_adr)

        response  = self.opener.open(request)

        tekst     = response.read()

        response.close()

        

        _,_, tekst = tekst.partition('ctl00_CT_FW_FolderLinksTable')

        tekst,_,_  = tekst.partition('ctl00_CT_FW_FilesUpdatePanel')

        #wyszukaj na stronie liste katalogow w katalogu, w ktorym sie znajdujemy

        res  = aut.findall(tekst)

        

        #wyszukaj katalog, do ktorego chcemy wejsc

        for i in res:

            if i[3] == directory:

                self.cur_adr = 'http://chomikuj.pl' + i[1]

                return


                

    def mkdir(self, name):

        """

        Tworzenie katalogu

        """

        request   = urllib2.Request(self.cur_adr )

        response  = self.opener.open(request)

        tekst     = response.read()

        

        ChomikID          = re.findall('
        ChomikSubfolderId = re.findall('
        SubfolderId       = re.findall('
        UploadToken       = re.findall('
        TokenTime         = re.findall('
        

        global httpdata

        postdata  = httpdata.format( ChomikID, ChomikSubfolderId, SubfolderId, UploadToken, TokenTime, urllib.quote(name))#nazwa tworzonego katalogu 

        request   = urllib2.Request(self.cur_adr )

        request.add_data(postdata)

        


        response  = self.opener.open(request)    

        response.close()



        

    def upload(self, filepath):

        request   = urllib2.Request(self.cur_adr)

        response  = self.opener.open(request)

        tekst     = response.read()

        response.close()  


        ChomikID          = re.findall('
        SubfolderId       = re.findall('
        UploadToken       = re.findall('
        TokenTime         = re.findall('
        #Wejdz na podstrone uploadowania pliku (nacisniecie na przycisk dodaj nowy plik)

        request = urllib2.Request('http://chomikuj.pl/ChomikUploadingFile.aspx?id={0}&sid={1}&tk={2}&t={3}'.format(ChomikID, SubfolderId, UploadToken, TokenTime), )


        response  = self.opener.open(request)

        #zapamietaj adres pod ktory zostalismy skierowani (znajduje sie tam m.in. nr serwera)

        tmp_url = response.geturl()

        #przeparsuj strone, aby znalezc formularz uploadowania pliku

        forms     = ClientForm.ParseResponse(response,backwards_compat=False)

        response.close()

        form = forms[0]

        #dodaj plik do formularza (niech to bedzie jakis plik tekstowy)

        form.add_file( open(filepath), "text/plain", "data.txt" )

        request   = form.click()

        #dodaj jeszcze do naglowka pole 'Referer'

        request.add_header('Referer', tmp_url)

        response  = self.opener.open(request)

        # w tym momencie nastepuje upload

        response.close()  

        

        

        

######################################################################################    

if __name__ == ' __main__':

    c = Chomik()

    print '\n\n\n\nLogowanie'

    c.login('tmp_chomik1', 'tmp_haslo')

    print '\n\n\n\nZmiana katalogu'

    #c.mkdir('śćąż')

    c.chdirs('/śćąż')

    #c.mkdir('prob aś7"')

    print '\n\n\n\nUploading'

    c.upload('proba.txt')

http://www.wklej.eu/index.php?id=7bca4ab97b

Oto co otrzymuję na wyjściu:

http://www.wklej.eu/index.php?id=9eaca1f436

A to jest mniej więcej ta sama sesja pod przeglądarką firefox (przy użyciu Live HTTP Headers)

http://www.wklej.eu/index.php?id=af376aacb3

Czy ktoś już pisał coś pod chomikuj.pl albo jakikolwiek uploader (np. pod rapidshare, megaupload…)? Czy ktoś ma pomysł jak napisać taki program?

Google -> twill

Obawiam się, że twill nie poradzi sobie z javascriptami, którymi został obsiany chomik. Przepisałem program, aby upload był wykonywany za pomocą czystych socketów (bez korzystania z urllib/urllib2) i zaczął działać. Jeżeli ktoś potrzebuje takiego bota, to mogę go później udostępnić.

Daj kod na pw albo tu, zerknę z ciekawości :slight_smile:

Dobry motyw jest z Selenium ale on otwiera przeglądarkę.

Także poproszę.

Kod programu wkleiłem tutaj:

chomik.py

http://www.wklej.eu/index.php?id=c36d86b07a

progress.py

http://www.wklej.eu/index.php?id=df091b4f45

Wrzuciłem także na mojego chomika

http://chomikuj.pl/adam_gr/ChomikUploader

Kod może nie jest najpiękniejszy, bo pisany na szybko, ale wysyłać pliki się da.