Autoit HTTP Post/Get ve Dosya Indirme Fonksiyonları

Öncelikle söylemek istediğim birşey var, ara ara çeşitli konu ve isteklerle mailler alıyorum. Bu maillere şu sıralar malesef cevap veremediğim için gönderen kişilerden özür dilerim :( Yoğunluk hiç bitmiyor. Bu yüzden vakit ayırıp okuyamıyorum bile. Neden bu kadar geç post attığım konusuna gelince, içeriği çalıp kendi forum veya blogunda yayınlayan, özellikle 2-3 kelime değiştirip google ı dahi kandırmaya çalışan sevgili arkadaşlar bilir diyelim :) 12milyon ranklı tertemiz bir blogdan içerik çalan çöp sitenin 80k ranklarda olmasıda ayrı tabiki. Bunları yazıyorum diye çalıp çırpmayı kesiceklermi? Tabi kesmiycekler, neyse önemli değil uzatmayalım konuya geçelim.

Autoit HTTP Post u anlatalım.
HTTP Post veya Get nedir bilmeyen veya bilende bilmeyen arkadaşlar için: Bir web sayfasına gönderdiğiniz değerler olarak açıklayabiliriz. Bunu bir form doldurup göndermek, login olmak gibi düşünün. Aslında bunun bugüne kadar: Form içinde Embed IE oluşturup sayfaya giderek ve inputları doldurup sayfayı göndererek yapıyordum. Bu işlem anlatımındada olduğu gibi gayet uzun süren bir işlem :P Sayfaya gitmek, yüklenmesini beklemek, sonra ,inputları id den alıp doldurmak ve gönder tuşuna basmak, sonra sayfanın yine yüklenmesini beklemek :P Çok uzun, çok. :P

HTTP Post komutları burada bize tek bir seferde duruma göre çok kısa süren bir işlemle bu işi yapmamıza yardımcı oluyor. Buna Paket gönderme deniyor. Paket TCP ile gidiyor.

Bize lazım olan lib: WinHTTP.au3

Basit bir Login örneği ile devam edelim:
Giriş yapmak istediğimiz sayfa www.test.com/login.php olsun.
Bu sayfada bir form içinde:
input type='text' name='username'
input type='password' name='pass'
olmak üzere 2 tane input var bunların birine e-postamızı birine şifremizi yazıyoruz görüldüğü üzere :P

Bunu WinHTTP komutlarıyla yapmak için oluşturduğum fonksiyon:

Func _SendPacket($sURL, $sSAYFA, $sDATA, $sREF, $sMETHOD = 'POST', $sSESSION = '')
Local $hOpen = _WinHttpOpen()
Local $hConnect = _WinHttpConnect($hOpen, $sURL)
Local $hRequest = _WinHttpOpenRequest($hConnect, _
$sMETHOD, _ ; metod, post veya get, bu formun türüne göre değişiyor
$sSAYFA, _ ; hedef sayfa /login.php?yap=login gibi, formun action sayfasına denk geliyor
Default, _ ; version
$sREF, _ ; referans url, formu gönderenin kimliğini belirliyor, aynı sayfa olması önemli.
"text/*") ; formun kabul ettiği tür, text,html,xml vesair.
_WinHttpSendRequest($hRequest, "Content-Type: application/x-www-form-urlencoded", $sData)
$resp = _WinHttpReceiveResponse($hRequest)
; Bakalım dönüş datası varmı. :)
Local $sChunk, $dat
If _WinHttpQueryDataAvailable($hRequest) Then
; Read
While 1
$sChunk = _WinHttpReadData($hRequest)
If @error Then ExitLoop
$dat &= $sChunk
WEnd
Else
Return FALSE
EndIf

_WinHttpCloseHandle($hRequest)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)

if($dat="") Then
Return FALSE
Else
Return $dat
EndIf
EndFunc

Bu fonksiyonu winhttp yi include ederek direk kullanabilirsiniz. $dat sayfadan dönen cevaptır.
Nasıl kullanacağımıza gelirsek, burada önemli olan nokta: $sDATA dır. Formdaki inputların değerlerini burada kullanacağız.
name='' deki değerlerimiz kullanıcı adı için : username şifre için: pass dı.
o halde: $data = "username=test&pass=12341234" olacak.

$login = _SendPacket("www.test.com", "/login.php", $data, "www.test.com/login.php", 'POST', '')
if $login <> FALSE then
msgbox(0, 'Sayfanın verdiği cevap', $login)
endif

Burda unutmamamız gereken cookie kontrol etmek ve eğer değişik karakterler kullanıyorsak göndermeden önce encode tarzı şeyler yapmak :P O kadar detaya inmedim, gerekirse yorumlarda haberleşiriz. Son olarak $sSESSION a gelirsek, bunu sayfa ile birlikte kullanım cache işlemlerine karşı önlem alabiliriz. $sSESSION = rasgele bir sayı değeri. $sSAYFA = "/login.php?session="&$sSESSION
Böylece cache ile aynı sayfayı 2 kere yükletmeyen site, herseferinde bizim için sayfayı yüklemek zorunda kalır :P

Dosya İndirme işlemine Gelirsek:
Autoit ile dosya indirmenin birçok yolu var.
TCP, InetGet, _InetGetSource, InetRead.

İndirdiğiniz dosyanın türünü biliyorsanız: _InetGetSource gayet esnekdir.
Verdiğiniz hedef dosyanın kaynak kodunu bir değişkene alır ve sizde bunu bildiğiniz uzantıyla bir dosyaya yazdırırsınız.

TCP ile TCPSend ve TCPRecv komutları ile tıpkı lan üzerinden dosya gönderip alır gibi dosya downloadı yapabilirsiniz. Hızlı ve güvenli bir yoldur. Sistem kaynaklarını doldurup pc yi yavaşlatmadan dosyayı indirir. Flashget, FDM, idman çoğu bu şekilde download yapıyor.

InetGet, direkt olarak dosyayı verdiğiniz konuma indirir :P

InetRead, _inetGetSource ile aynı sayılır, bu fonksiyonda verilen hedefdeki kaynağı okuyup bir değişkene atamakta kullanılabilir.

Değişkene atadığımız fonksiyonlar büyük downloadlar ile hiç sağlıklı değildir. Açıklamak gerekirse, yaptığımız ufak bir download yazılımı, sistemin raminden 3mb kullanan bir download yazılımı, 1gb bir dosyayı inetRead ile veya inetGetSource ile almaya çalışırsak, download bitiminde 1GB ram kullanır pozisyona gelir. Bunun yerine TCP ile okuduğumuz kadarını değişkende tutmadan direk dosyaya yazdırmak en iyi yoldur.

Autoit ile dosya indirme nin detayını önümüzdeki günlerde yeni bir makale ile yazmayı düşünüyorum, bu makale çok uzadı. Görüşmek üzere, aklınıza takılan bir soru varsa yorumlayabilirsiniz, birlikte cevaplamaya çalışırız.

3 yorum:

Ahmet Uğur dedi ki...

313 Gercek adını bilmesekte , Blogun ilk acıldıgı günden beri sizi takip ediyorum. Taha(RouteBlazin) ile birlikte cok projeler gercekleştirdik sayenizde. Kolay bir kontrol programı için ideal bir yazılım.

Sorun şudurki bir poster yapmıstım, IE embed ile form üzerine IE sayfası yapıp kullanıyordm . iexplorer.exe yi acmak kapamak cok sorun oluyordu ve görümemesi gerekiordu ne kadar Hide etsekte hep sorun oluyordu .

Suan hala IE embed ile kullanıyorm ve bir süreden sonra ram çok şişiyor , her sayfa değiştiğinde artıyor . Post metodunu gecen hafta bir sayfada denedim iyi calısıyordu ama RAM için yapmamıstım bunu .


Bu verdiğiniz kodları deneyeceğim , ama sanıyorum bu fonksiyon ram yemeyecektir . Eğer yiyorsa düşürmenin yolu nedir neden böyle bir şey yapıyor çözebilmiş değilim. yeni IE olusturmak yerine Navigate kullanıyorum .

Ve birde :) Uzun zamandır au3 kullanıyorum ve bundan önce Delphi kullanıyordm ve Timer lar cok işime yarayıp birden fazla fonksiyonu aynı anda kullanabiliyordum , au3 de böyle bir imkan varmı :)


Şimdiden teşekürler .

Ahmet Uğur dedi ki...

Hocam yapamadım bir türlü yardım ederseniz sevinirim. Vbulletin de konu actıran bir şey deniyorum .

form action = newthread.php?do=postthread&f=43

başlık input name'i = subject
mesaj yazma yeri textarea taglı name'i = message

ve birde html form olsuturup denediğim , olmazsa olmaz input değerleri . Bunları nasıl entegre edebilrim vbulletine . Ve Aşağıdaki valueler her seferinde değişiyor yani sürekli almak gerekiyor . Winhttp de o değerleri get edicek bir kod bulamadım. Yardm edersen sevinirim .


div style="margin-top:0px">
input type="hidden" name="s" value="">
input type="hidden" name="securitytoken" value="1305513371-ec1ab76b082a04ac88b09973a6f19d956d030010">
input type="hidden" name="f" value="43">
input type="hidden" name="do" value="postthread">
input type="hidden" name="posthash" value="2f646877d65e4228ce436e52dcc0b9ce">
input type="hidden" name="poststarttime" value="1305513371">
input type="hidden" name="loggedinuser" value="1">
input type="submit" class="button" name="sbutton" id="vB_Editor_001_save" value="Konuyu aç" accesskey="s" tabindex="1">
input type="submit" class="button" name="preview" value="Önizleme" accesskey="r" tabindex="1">
/div>

313 dedi ki...

Tşk ederim ahmet kardeşim takip etmene sevindim, bu blog benimde severek makale eklediğim bir yer. Şu sıralar php ye çok fazla kaptırdığımdan autoit ile eskisi kadar ilgili değilim ama yinede hobi olarak arada birşeyler yapıyorum.

Ram şişmesi konusunda söyleyebileceğim, kaynakları boşaltman olacaktır. Çünkü değişken arttıkça, ki bu değişkenler özellikle fileread, inetgetsource gibi değerlere atanıyorsa ram kullanımıda artacaktır.

Bir dosyayı okutup değişkene atadığında,
$kaynak = fileread(test.txt) diyelim,
o dosyanın boyutu neyse autoit script ramde o kadar daha yer kaplamaya başlar. aynı şey inetgetsource içinde gerekli. Ha birtek bu tarz olmayabilir, çok fazla 1 kereye mahsus kullanılan değişkeni daha sonra serbest bırakmamış olabilirsin. Diyelimki bir web sayfasının kaynağını aldın,
$kaynak = inetread(www.google.com),
bunu kullandıktan sonra bir daha işine yaramayacaksa,
$kaynak = "",
yapman ramden kazanmana yardımcı olur.
Belkide bunu biliyorsundur, gözden kaçırmış olabilirsin, incelemen gerekli.

Post konusuna gelince, gayet karmaşık ve uğraştıran birşey. Heleki vBulletin gibi sağlam ve güvenlik önlemi olan yazılımlarda dahada zorlaşıyor.

Öncelikle, mozillada http izleyen yazılımlar var, formu gönderdiğinde hangi verilerin gittiğini takip etmen gerekli. Yanlızca görünen inputlar değil, görünmeyenlerde güvenlik için gerekli olabilir. Burda gördüğüm kadarıyla bir ton hidden var :) Bu hiddenlerin hepsini post satırına eklemen lazım ki vBulletin formun gerçekten gönderildiğini anlasın.

Tahminen göndereceğin form query si şöyle olabilir:
$post = newthread.php?do=postthread&s=&securitytoken={değişken_değer}&f=43&posthash={değişken_olabilir}&poststarttime={değişken_olabilir}&loggedinuser=1

Burada önemli olan ilk olarak şu, Eğer herşeyi post ile yapacaksan, ilk başta login olmayı unutmaman gerek yani direk konu açma sayfasından başlamak yerine login.php den başla.

Değişken değerleri alma konusunda gelirsek: Evet, güvenlik nedeniyle onları anlık olarak alman şart, yoksa postun fake olduğunu vBulletin anlayacaktır.
_INetGetSource() ile alıp bir deneyebilirsin ama bununda olacağından şüpheliyim çünkü aynı oturum üzerinde gerçekleştirmek gerekebilir.
Örnek vermek gerekirse php de bu sistem şu şekilde işliyor:

$oturum = oturum aç(www.google.com)
loginegit(www.google.com/login.php, $oturum)
loginyap($post, $oturum)
postsayfasınagit(www.google.com/yenikonu.php, $oturum)
postyap($post, $oturum)
anasayfayadon(www.google.com, $oturum)
oturumukapat()

Bunu winHTTP ile yapmakta illaki mümkündür ancak hiç denemediğim için nasıl yapıldığını bilmiyorum, autoit forumlarında winhttp login + post olarak aratırsan birşeyler çıkacağından eminim, yinede yapamazsan birlikte tekrar deneriz.

_inetGetsource ile kaynağı aldıktan sonra,
ilk basta geciciveriler diye bos bir değişken oluşturmalısın.
$inputlar = _StringBetween(başlangıç="<input", bitiş="/>)
olarak alırsan, tüm inputlar gelir, daha sonra bunların içinde:
if(stringinstr($inputlar[$i], "hidden"))then
dersen, içinde sadece hidden geçen inputları bulabilirsin.
Bundan sonra, _stringbetween('value="', '"')
yaparak bunların değerlerini,
_stringbetween('name="', '"') yaparakda isimlerini alabilirsin.

$geciciveriler &= "&name=value"
endif

son olarak, $post &= $geciciveriler,
postyap($post)

Biraz karışık oldu kusura bakma :D Ne yaptığını bilmek için winhttp sonucunda gelen header bilgilerini okuman yardımcı olabilir.
Allah kolaylık versin, yapamazsan yine yaz birlikte bakalım.

Yorum Gönder