PDA

View Full Version : دریافت فایل با لینک مستقیم (از شبکه) با داشتن نام کاربری و کلمه عبور (مثل رپیدشیر)



SMRAH1
پنج شنبه 01 مرداد 1388, 21:03 عصر
سلام

من تصميم دارم يک Downloder ساده بنويسم.به همين منظور از کد زير براي دريافت يک فايل استفاده مي کنم (اين کد هسته اصلي است و نه کد کامل ،اگر متغيري تعريف نشده است به شکل مناسب فرض کنيد)


void GetFile(string FromUrl, string ToFile)
{
const int LenRead = 1024;
byte[] buffer = new byte[LenRead];

HttpWebRequest fr = (HttpWebRequest)WebRequest.Create(new Uri(FromUrl));
fr.Method = WebRequestMethods.Http.Get;
WebResponse response = fr.GetResponse();
Stream stream = response.GetResponseStream();

fStream = new FileStream(ToFile, FileMode.OpenOrCreate, FileAccess.Write);
fStream.SetLength(0);

int totalRead = stream.Read(buffer, 0, buffer.Length);
while (totalRead > 0)
{
fStream.Write(buffer, 0, totalRead);
totalRead = stream.Read(buffer, 0, LenRead);
}

stream.Close();
fStream.Close();
}اين کد براي دريافت فايل ها با داشتن لينک مستقيم کاربري دارد و عمل مي کند.اما مشکل من از جايي آغاز مي شود که بخواهم فايلي را با داشتن نام کاربري و رمز عبور دريافت کنم (مثلا از رپيدشير - فرض اين است که من نام کاربري و رمز عبور را دارم - اين کار به راحتي با Downloder هايي مثل FlashGet و ... شدني هستند).طبق مثال هايي که ديدم بايد از کدي شبيه زير براي اين منظور استفاده کنم:


void GetFile2(string FromUrl, string ToFile,string UserName,string Pass)
{
const int LenRead = 1024;
byte[] buffer = new byte[LenRead];

NetworkCredential nc = new NetworkCredential(strUserName, strPassword);
MyCredentialCache = new CredentialCache();
MyCredentialCache.Add(new Uri(FromUrl),"Basic",nc);

HttpWebRequest fr = (HttpWebRequest)WebRequest.Create(new Uri(FromUrl));
fr.Method = WebRequestMethods.Http.Get;
fr.Credentials = MyCredentialCache;
WebResponse response = fr.GetResponse();
Stream stream = response.GetResponseStream();

fStream = new FileStream(ToFile, FileMode.OpenOrCreate, FileAccess.Write);
fStream.SetLength(0);

int totalRead = stream.Read(buffer, 0, buffer.Length);
while (totalRead > 0)
{
fStream.Write(buffer, 0, totalRead);
totalRead = stream.Read(buffer, 0, LenRead);
}

stream.Close();
fStream.Close();
}اما اين کد عمل نمي کند! (کد هاي آماده اي هم گرفتم که عمل نمي کنند).
سئوال من اين است : براي دريافت يک فايل (مثلا از رپيدشير با فرض هاي بالا)،دقيقا از چه کدي بايد استفاده کرد.(لطفا اگر ممکن است کد کامل باشد يا راهنمايي جامع!)

متشکرم

13601360
پنج شنبه 01 مرداد 1388, 22:58 عصر
این نمونه برنامه رو ببینید دوست عزیز امیدوارم کمکتون کنه


Simple Upload File to Rapidshare Account Method



http://www.codeproject.com/KB/IP/Upload_To_Rapidshare.aspx

Sajjad.Aghapour
جمعه 02 مرداد 1388, 00:19 صبح
چرا از WebClient استفاده نمی کنید......
من هم یه همچین پروژه ای رو تا یه جایی رسوندمش که به دلیل مشغله نتونستم کاملش کنم.البته من دنبال resume بودم که قسمت نشد زیارتش کنم:لبخند:.....

SMRAH1
جمعه 02 مرداد 1388, 16:30 عصر
سلام

جناب 13601360،مقاله جالبی بود (در رابطه با Upload فایل در Rapidshare است).هرچند کمکی نکرد ولی اطلاعات خوبی در اختیارم گذاشت.به دوستان توصیه می کنم حتما ملاحظه کنند.
جناب sajjadlove،استفاده از WebClient همچنان همان مشکل را دارد (تشخیص کاربر توسط سایت) و البته کمی غیر اصولی به نظر می رسد.

با این حال یک راه حل (هرچند کمی غیر اصولی است ولی شدنی) پیدا کرد.اما قبل از آن به ذکر برخی نتایج در جستجو هایم اشاره می کنم (شاید برای دیگران مفید باشد).
در codeplex،پروژه هایی برای همین منظور هستند که سه تای آنها مفید تر بنظر می رسند(خودم هیچ یک را آزمایش نکردم) :
RapidShare Downloader.NET (http://rsdownloader.codeplex.com/) : برای دانلود توسط Free User از سایت رپیدشیر.این برنامه از WebClient در پشت صحنه استفاده کرده و بعد از تجزیه و تحلیل آن عملیات مورد نظر را انجام می دهد (مثلا اینکه چند ثانیه تا دانلود باید صبر کند و بعد دکمه دانلود را بزند!).ایراد این روش (همانطور که در اسنادش آمده است)،این است که کاملا وابسته به فرمت صفحه است (اگر فرمت صفحه رپیدشیر عوض شود،برنامه کار نخواهد کرد!).
Rapidshare admin (http://rsadmin.codeplex.com/) : این نیز یک پروژه ویندوزی است که با تحلیل اطلاعات ارسالی توسط رپیدشیر،می توان عملیات ها و اطلاعات های Premium Account رو نمایش یده (مثل امتیاز و ... همچنین Upload فایل).
SynoManager (http://synomanager.codeplex.com/) : این هم یک پروژه ویندوزی دیگر است که با استفاده از یک سرور میانی ،فایلهای را از سرور رپیدشیر دریافت و به برنامه ارسال می کند.

اما در اینجا (http://vahidnasiri.blogspot.com/2009/02/resume-httpwebrequest.html)از آقای «وحید نصیری» نکته ای دیدم که در مورد Resume بود (حتما مطالعه کنید).در همین جا نیز تاکید شده که در رپیدشیر «اكانت پرميوم از basic authentication استفاده ميكنه» ،که اگر اینطور باشه باید کد بالا کار کنه (در پست اول) که البته کار نمی کنه (در جاهای مختلف هم دیدم که کاربران عدم کارکرد رو نوشتن و سئوال کردند!).البته کد های پیشرفته تر هم (در MSDN اطلاعات مربوط به کلاس AuthenticationManager رو ببینید) کار نمی کنه!

اما در نهایت در اینجا (http://fedoracoreproject.blogspot.com/2009/03/linux-command-line-tool-to-download.html)نکته ای رو دیدم (هر چند مربوط به wget در لینوکس است) که به من کمک کرد تا بتونم یک ایده بدست بیاورم : «اول توسط CookieContainer خودم رو ثبت کنم و بعد دانلود رو انجام بدم»

پس سه مرحله رو باید دنبال کنم :
1) تعیین آدرس دقیق : برای نمونه آدرس فایل زیر رو در نظر بگیرید (آدرس اصلی) :

http://rapidshare.com/files/257630419/A.mdb
در واقع آدرس دقیق

http://rs429.rapidshare.com/files/257630419/A.mdb
است که نام سرور در ابتدا گذاشته شده است (فرق آدرس دقیق با آدرس اصلی در نام سرور است).البته اگر صفحه آدرس اصلی رو بگیرید،در کد HTML آن آدرس دقیق آمده است.کد زیر با دریافت آدرس اصلی و بارگذاری صفحه ،آدرس دقیق رو پیدا می کنه:

private static string GetCorrectUri(string strSrcURI)
{
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create(strSrcURI);
Request.Method = "GET";
WebResponse Response = (HttpWebResponse)Request.GetResponse();
StreamReader ResponseStream = new StreamReader(Response.GetResponseStream());
string result = ResponseStream.ReadToEnd();
ResponseStream.Close();

int end = strSrcURI.IndexOf("rapidshare");
string Addr = strSrcURI.Substring(end);

end = result.IndexOf("." + Addr);
result = result.Substring(0, end);

int start = result.LastIndexOf('/');
string server = result.Substring(start + 1);
string url = String.Format("http://{0}.{1}", server, Addr);
Console.WriteLine(url);
return url;
}
2) با استفاده از premiumzone.cgi خودم رو ثبت می کنم و کوکی مورد نظر رو دریافت می کنم یعنی :

private static CookieContainer GetCookies()
{
CookieContainer cookies = new CookieContainer();
HttpWebRequest Request = (HttpWebRequest)HttpWebRequest.Create("https://ssl.rapidshare.com/cgi-bin/premiumzone.cgi");
Request.Method = "POST";
Request.CookieContainer = cookies;

string postData = "login=" + username + "&password=" + password;
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte1 = encoding.GetBytes(postData);

// Set the content type of the data being posted.
Request.ContentType = "application/x-www-form-urlencoded";

// Set the content length of the string being posted.
Request.ContentLength = byte1.Length;

Stream newStream = Request.GetRequestStream();

newStream.Write(byte1, 0, byte1.Length);
newStream.Close();

return cookies;
}
3) در نهایت فایل رو با استفاده از کوکی ثبت خودم ،دریافت می کنم :

static void Main2()
{
// Variables.
HttpWebRequest Request;
WebResponse Response;
string strSrcURI = uri;
string strUserName = username;
string strPassword = password;
string strDomain = domain;
Stream ResponseStream;

try
{
// Create the HttpWebRequest object.
Request = (HttpWebRequest)HttpWebRequest.Create(GetCorrectUr i(strSrcURI));

// Specify the method.
Request.Method = "GET";

Request.CookieContainer = GetCookies();

// Send the GET method request and get the
// response from the server.
Response = (HttpWebResponse)Request.GetResponse();

// Display the item's stream content type and length.
Console.WriteLine("Content type: " + Response.ContentType);
Console.WriteLine("Content length: " + Response.ContentLength);
long AllSize = Response.ContentLength;

// Create the stream reader object with the
// response stream.
ResponseStream = Response.GetResponseStream();

Byte[] read = new Byte[1024];

FileStream fStream = new FileStream("Get2.bin", FileMode.OpenOrCreate, FileAccess.Write);
fStream.SetLength(0);

Console.WriteLine("Begin ----");

int bytes = ResponseStream.Read(read, 0, 1024);
int Size = bytes;
while (bytes > 0)
{
Console.Write(((int)(((double)Size/AllSize)*100)).ToString() + "% ");
fStream.Write(read, 0, bytes);
bytes = ResponseStream.Read(read, 0, 1024);
Size += bytes;
}
fStream.Close();
Console.WriteLine();
Console.WriteLine("End ----");

// Clean up.
fStream.Close();
Response.Close();
ResponseStream.Close();

}
catch (Exception ex)
{
// Catch any exceptions. Any error codes from the GET
// method request on the server will be caught here, also.
Console.WriteLine(ex.Message);
}
}

در پایان تاکید می کنم که اگر از دوستان کسی راه دیگری را (بر مبنی basic authentication که جواب بده) سراغ دارد،حتما راهنمایی بفرماید.
کد زیر هم یک فرم ساده با استفاده از thread ها در این زمینه است.

از دوستان متشکرم
موفق باشید

13601360
جمعه 02 مرداد 1388, 17:07 عصر
ممنون از دوستمون SMRAH1 به خاطر مقاله عالی شون :تشویق:
من از خدمتون یه سوال داشتم به نظر شما میشه این مقاله رو در مورد آپلودر های دیگه هم به کار برد.
البته ربطی به این موضوع نداره ولی یه Script php هست به نام Rapidleech که دقیقا کاری مثل برنامه شما می کنه ولی برای حدود 50 آپلودر , یعنی لینک دانلود مورد نظر رو به اون می دید. فقط مسیر ذخیره سازیش توی پوشه ای در خود هاست هست
ولی اگر بشه یه نسخه ویندوزی از اون ساخت چیز جالبی میشه :متفکر:

SMRAH1
جمعه 02 مرداد 1388, 17:18 عصر
سلام
اتفاقا این PHP که گفته بودید در Google Code Search دیدم و نکات جالبی داشت.
برای استفاده در رابطه با دیگر سایت ها هم بسته به نوع سایت دارد.مثلا در سایت letitbit شما باید در صفحه ای که باز می شود ،پسورد خود را وارد کنید و بعد دکمه مشخص شده را بزنید تا در صفحه دیگری ،یک لینک مستقیم به فایل درخواستی برای شما ارسال شود.(فایل مستقیما ارسال نمی شود بلکه لینک مستقیم می دهد - کوکی ندارد - برای هر بار دانلود باید پسورد را وارد کنید).
البته از ایده کلی (که معمولا استفاده می شود و مثالی هایی از آن را در CodePlex مطرح کردم) یعنی پرداز صفحه می توان استفاده کرد ولی باید توجه کرد « کاملا وابسته به فرمت صفحه است» که این خود نقطه ضعف بزرگی است.

موفق باشید