2011-12-08 18 views
18

Sto tentando di accedere a Facebook nel mio programma e analizzare alcune informazioni da lì (come nome, immagine del profilo, ecc.).C# - HttpWebRequest POST (Login a Facebook)

Sono reindirizzato alla pagina principale di Facebook ogni volta che eseguo il codice qui sotto.

string email = "email"; 
string pw = "pw"; 
string PostData = String.Format("email={0}&pass={1}", email, pw); 

CookieContainer cookieContainer = new CookieContainer(); 

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(""); 
req.CookieContainer = cookieContainer; 
req.Method = "POST"; 
req.ContentLength = PostData.Length; 
req.ContentType = "application/x-www-form-urlencoded"; 
req.AllowAutoRedirect = true; 
req.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"; 

ASCIIEncoding encoding = new ASCIIEncoding(); 
byte[] loginDataBytes = encoding.GetBytes(PostData); 
req.ContentLength = loginDataBytes.Length; 
Stream stream = req.GetRequestStream(); 
stream.Write(loginDataBytes, 0, loginDataBytes.Length); 

HttpWebResponse webResp = (HttpWebResponse)req.GetResponse(); 

Stream datastream = webResp.GetResponseStream(); 
StreamReader reader = new StreamReader(datastream); 
webBrowser1.DocumentText = reader.ReadToEnd(); 

foreach (Cookie cookies in webResp.Cookies) 
{ 
    MessageBox.Show(cookies.Name + " " + cookies.Value); 
} 

Cosa sto facendo di sbagliato qui? Qualsiasi aiuto sarebbe apprezzato, molte grazie! :)

modifica: Ho scoperto come farlo poco dopo l'invio.

Facebook invia un cookie ogni volta che lo si visita per vedere se i cookie sono abilitati, quello che ho fatto è stato inviare una richiesta alla pagina di accesso di Facebook per ottenere i cookie, quindi inviare un altro con i dati POST. Ha funzionato in questo modo e l'accesso è stato effettuato correttamente.

Grazie comunque! :)

+0

Hai letto sul API di Facebook http://developers.facebook.com/blog/post/395/ o http://facebooksdk.codeplex.com/ – Lloyd

+2

Questo è contro i termini di Facebook del servizio . – bkaid

+0

Spesso devo usare il controllo webrwser invece di HttpWebRequest a causa di questo tipo di motivi. Questa domanda mi dà fastidio qualcosa di nuovo ... Inoltre, anche se è di nuovo sui termini di servizio di Facebook, potrebbe essere usato per cose etiche .... –

risposta

5

A volte è più semplice utilizzare il browser Web ed è possibile eseguire quel browser nascosto in background. Più tardi puoi ottenere l'html interno o forse scaricare un'immagine. Qualunque cosa tu abbia bisogno di fare Ecco un esempio che utilizza i moduli di Windows.

Creare una nuova applicazione di moduli di vincita, aggiungere un pulsante e incollarlo all'interno. non aggiungere niente altro dovrebbe funzionare ...

private void button1_Click(object sender, EventArgs e) 
{ 
    string email = "Your email"; 
    string password = "your password"; 

    // create a new browser 
    WebBrowser w = new WebBrowser(); 
    w.Dock = DockStyle.Fill; 
    this.Controls.Add(w); // you may add the controll to your windows forms if you want to see what is going on 
    // latter you may not chose to add the browser or you can even set it to invisible... 


    // navigate to facebook 
    w.Navigate(@"http://www.facebook.com/"); 

    // wait a little 
    for (int i = 0; i < 100; i++) 
    { 
     System.Threading.Thread.Sleep(10); 
     System.Windows.Forms.Application.DoEvents(); 
    } 


    HtmlElement temp=null; 

    // while we find an element by id named email 
    while (temp == null) 
    { 
     temp = w.Document.GetElementById("email"); 
     System.Threading.Thread.Sleep(10); 
     System.Windows.Forms.Application.DoEvents(); 
    } 

    // once we find it place the value 
    temp.SetAttribute("value", email); 


    temp = null; 
    // wiat till element with id pass exists 
    while (temp == null) 
    { 
     temp = w.Document.GetElementById("pass"); 
     System.Threading.Thread.Sleep(10); 
     System.Windows.Forms.Application.DoEvents(); 
    } 
    // once it exist set it value equal to passowrd 
    temp.SetAttribute("value", password); 

    // if you already found the last fields the button should also be there... 

    var inputs = w.Document.GetElementsByTagName("input"); 

    int counter = 0; 
    bool enableClick = false; 

    // iterate through all the inputs in the document 
    foreach (HtmlElement btn in inputs) 
    { 

     try 
     { 
      var att = btn.GetAttribute("tabindex"); 
      var name = btn.GetAttribute("id"); 

      if (enableClick)// button to submit always has a differnt id. it should be after password textbox 
      { 
       btn.InvokeMember("click"); 
       counter++; 
      } 

      if (name.ToUpper().Contains("PASS") || att=="4") 
      { 
       enableClick = true; // button should be next to the password input      
      } 

      // try a max of 5 times 
      if (counter > 5) 
       break; 
     } 
     catch 
     { 

     } 
    } 
} 
+1

Facebook ha un'API per un motivo che raschia l'HTML non è una proposta decente per quello che la domanda propone . – Lloyd

+0

Ho affermato che la soluzione non era la migliore nella mia risposta. La mia soluzione funziona. Sono sicuro che ci saranno soluzioni migliori ma non penso di meritare il -1 per una soluzione funzionante. –

+0

Non l'ho annotato! – Lloyd

-4

Stai Tring passare parametro login alla pagina facebook di accesso ?? Se sì, Facebook non permette di farlo da qualsiasi modo ...

34

Sono contento che hai trovato la tua risposta, ho potuto effettuare il login utilizzando facebook HttpWebRequest troppo, proprio come hai detto .. Ecco una soluzione accettabile:

Primo richiesta: Ricevi i cookie.

CookieCollection cookies = new CookieCollection(); 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.facebook.com); 
request.CookieContainer = new CookieContainer(); 
request.CookieContainer.Add(cookies); 
//Get the response from the server and save the cookies from the first request.. 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
cookies = response.Cookies; 

Second richiesta: POST i dati del modulo e recuperare i cookie dal prima richiesta ..

string getUrl = "https://www.facebook.com/login.php?login_attempt=1"; 
string postData = String.Format("email={0}&pass={1}", "value1", "value2"); 
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl); 
getRequest.CookieContainer = new CookieContainer(); 
getRequest.CookieContainer.Add(cookies); //recover cookies First request 
getRequest.Method = WebRequestMethods.Http.Post; 
getRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"; 
getRequest.AllowWriteStreamBuffering = true; 
getRequest.ProtocolVersion = HttpVersion.Version11; 
getRequest.AllowAutoRedirect = true; 
getRequest.ContentType = "application/x-www-form-urlencoded"; 

byte[] byteArray = Encoding.ASCII.GetBytes(postData); 
getRequest.ContentLength = byteArray.Length; 
Stream newStream = getRequest.GetRequestStream(); //open connection 
newStream.Write(byteArray, 0, byteArray.Length); // Send the data. 
newStream.Close(); 

HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse(); 
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
{ 
    string sourceCode = sr.ReadToEnd();    
} 

Questo è uno dei modi lotti che funziona con HttpWebRequest, anche se si preferisce utilizzando WebBrowser, funziona accettabile utilizzando il seguente:

webBrowser1.Navigate("https://www.facebook.com/login.php?login_attempt=1", "",byteArray, "Content-Type: application/x-www-form-urlencoded"); 

Quello che ho appena capito è che non funziona con il InternetSetCookie forse il motivo è perché i cookie restituiti da Facebook hanno l'attributo "HttpOnly" (true), e non può essere accessibile dallo script lato client.

+0

Eccellente! Era quello che stavo cercando. Bello, pulito, completo. Ottimo, grazie mille. –

+0

Prego! ma ricorda che questo è contro i Termini di servizio di FB, dato che lo facciamo solo a scopo educativo, usalo saggiamente! Cheers @ patryk.beza – WhySoSerious

+0

wow. è carino . .. grazie:.) –

-1
webbrowser1.navigate("www.facebook.com"); 
webbrowser1.GetElementByiId("email").value="your mail ID"; 
webbrowser1.GetElementByiId("pass").value="password"; 
HtmlElement form = webBrowser1.Document.GetElementById("FormID"); 
if (form != null) 
form.InvokeMember("submit"); 
+1

per favore potete aggiungere un commento che indica il motivo per cui si ritiene che il codice è una soluzione a questo problema? – Trinimon

+0

c'è ancora nessun commento e questo è solo un modo per riempire il forma automaticamente. – djsony90