Olen tekemässä ohjelmaa joka lataa netistä eräältä sivulta tietoa ja käsittelee niitä haluamallani tavalla. Tietojen lataus onnistuisi mainioisti tällä, mutta kun sivulle pitäisi kirjautua ennen kuin tiedot saa näkyviin.
Eli ohjelman pitäisi kirjoittaa pääsivulle käyttäjätunnus ja salasana ja sitten vielä painaa "kirjaudu" nappia.
Mites tällainen toteutetaan.... vinkkejä tms kaipailen.
Voit käytää luokkaa HttpWebRequest. Tekstikentän täyttäminen ja lähettäminen tarkoittaa käytännössä tietynlaisen datan lähettämistä palvelimelle, ja tämän voit selvittää vaikkala Firefoxin Live HTTP Headers -lisäosan avulla.
Moikka taas novice!
lainataan tätä täältä ja muutetaan hieman...
Imports System Imports System.Net Imports System.Text '... Dim wc As New WebClient() Dim cc As New CredentialCache() Dim Url As String = "http://www.esimerkki.com/" cc.Add(New Uri(Url),"Basic", _ New NetworkCredential("tunnuksesi","salasanasi")) wc.Credentials = cc Dim tieto As String = Encoding.ASCII.GetString( _ wc.DownloadData(Url & "tietoa.txt")) TextBox1.Text = tieto wc.Dispose
Mihin textboxiin tuo networkcredential laittaa tunnuksen ja salasanan ja minkä formin se lähettää eteenpäin?
Moikka Short Php!
Jos luit mitä Metabolix kirjoitti, niin lienee selvinnyt, että mitään textboxeja ei tässä täytellä fyysisesti...
Eipä onnistunut... Metabolix:n vinkki pölisi yli hilseen (ehkäpä se aukeaisi jos löytyisi kunnollinen esimerkki) ja Neaun vinkillä sain sivulta ulos seuraavan; "You cannot use this function".
En tiedä sitten mitä tein väärin... voiko tuon CredentialCache kirjautumisen estää?
Moikka taas novice!
Kyllä on mahdollista estää palvelinpäässä CredentialCache'n käyttö
elikä: ...security.util.CredentialCacheEnabled = false
Opera selaimeni osaa kuitenkin kirjautua sivulle, joten jollain tavallahan sen on onnistuttava.
Onko seuraa etappi HttpWebRequest luokan opiskelu? Olisin kiitollinen esimerkistä...
Jos oikein ymmärsin, niin se ei kysy http-protokollan tasolla käyttäjätunnusta ja salasanaa, vaan siinä on kirjautumislomake. Eli mikäli nyt en ihan väärin arvaa, niin tuosta networkcredentialista ei ole hyötyä.
Se mahdollisesti antaa evästeen, joka pitäisi välittää myöhemmissä sivuissa. Jos näin, niin kannattaa tutustua miten evästeitä käytetään HttpWebRequestin kanssa.
WOW Grez!
You really are an incredible man!
Moi Nea, on se hyvä jos pienellä luetunymmärtämisellä pääsee uskomattomaksi...
Vai mitä mahdoit tarkoittaa?
Okei.. sivulle kirjauduttaessa evästeet on oltava päällä.
Aloin tutkailemaan HttpWebRequest-luokkaa ja Firefoxin Live HTTP Headers -lisäosaa. HTTP Headers:n avulla (jos nyt oikein sitä käytin/tajusin) selvitin, että ladattaessa sivu lähettää selaimelle evästeen ja sisään kirjauduttaessa selain lähettää sivulle saman evästeen. Sen jälkeen aina uutta sivua (samasta osoiteesta) ladattaessa lähettää sivu selaimelle saman evästeen. Eikä selain kirjautumisen jälkeen enää postaa evästettä mihinkään.
Nyt pitäisi VB ohjelmalla saada se eväste ja postata se kirjautumisen yhteydessä sivulle. Yritin seuraavaa, mutta sain textboxiin vain sivun lähdekoodin jossa ei ole tätä tarvitsemaani evästettä.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim URL As String = "http://www.esimerkki.com/index.php" Dim Request As HttpWebRequest = WebRequest.Create(URL) Request.UserAgent = _ "Mozilla/5.0 (Windows; U; Windows NT 5.1; fi; rv:1.9.0.5) _ Gecko/2008120122 Firefox/3.0.5 (.NET CLR 3.5.30729)" Request.Method = WebRequestMethods.Http.Get Dim Response As HttpWebResponse = Request.GetResponse() Dim reader As New StreamReader(Response.GetResponseStream()) Dim tmp As String = reader.ReadToEnd() Response.Close() TextBox1.Text = tmp End Sub
Miten saan evästeen textboxiin?
Tiedän että olen aika kartanolla ja oikeat termit ovat hakusessa... koettakaa siitä huolimatta ymmärtää ja auttaa miestä mäessä.
No kun näitä on niin hirveen tylsää demota ilman että on se sivu josta ne tiedot pitäisi hakea.. (etkä nähtävästi halua kertoa mikä se on) joten tein tollaisen demosivun joka vaatii keksit ja jolle pitää ensin kirjautua
http://grez.info/putka/novice/
Käyttäjätunnus on novice ja salasana ecivon
Nyt kun meillä on sivu, jolla testata, niin voidaan tehdä ohjelma, joka ohjelmallisesti kirjautuu ja hakee tiedot... Esimerkiksi näin:
Imports System.Net Imports System.IO Module Salanoutaja Sub Main() 'Tarvitsemme keksipurkin. Se on vähän kuin Nalle Puhin hinajapurkki, 'mutta siinä ei ole hinajaa vaan keksejä eli evästeitä. Dim Cookies As New CookieContainer 'Kirjaudutaan Dim request As HttpWebRequest = WebRequest.Create("http://grez.info/putka/novice/") 'Annetaan keksipurkki, johon webrequest voi laittaa saamansa keksit request.CookieContainer = Cookies request.Method = "POST" request.ContentType = "application/x-www-form-urlencoded" 'Kirjauduttaessa lähetetään käyttäjätunnus ja salasana palvelimelle Dim bytes() As Byte = System.Text.Encoding.Default.GetBytes("user=novice&pass=ecivon") request.ContentLength = bytes.Length Dim outputStream As System.IO.Stream = request.GetRequestStream() outputStream.Write(bytes, 0, bytes.Length) outputStream.Close() Dim Response As WebResponse = request.GetResponse() 'Kirjautuminen on lähetetty, voidaan sulkea Response.Close() 'Ladataan salainen sivu request = WebRequest.Create("http://grez.info/putka/novice/sisalto.php") 'Käytetään samaa keksipurkkia, niin selain saa takaisin lähettämänsä keksit request.CookieContainer = Cookies Response = request.GetResponse() Dim reader As StreamReader = New StreamReader(Response.GetResponseStream, System.Text.Encoding.Default) 'Luetaan vastaus Dim Vastaus As String = reader.ReadToEnd reader.Close() Response.Close() 'Näytetään salaiset tiedot käyttäjälle Console.Out.Write(Vastaus) End Sub End Module
WOW Grez!
You really are an incredible man!
Sehän toimi hienosti... välistä puuttui vain yksi lause:
request.ProtocolVersion = HttpVersion.Version10
Eikä mennyt kuin 8h että tuon keksin väliin tyrkätä.
Mutta no... tuon 8h aikana tuli HttpWebRequest-luokka hieman tutummaksi ;)
Suuret kiitokset sinulle Grez!!!
Tuolla esimerkkisivullani kyllä toimi (ainakin itselläni) ilman tuota ja tuon kanssa taas luulen että tuo esimerkkisivuni ei toimi (HTTP 1.0:ssa kun ei ole host headeria jota useita www-sivuja yhdessä IP:ssä hostattaessa tarvii)
Mutta ilmeisesti tarkoititkin sen sivun kanssa, johon tuota itse tarvitsit. (Tosin siinäkin olisi mielenkiintoista tietää mikä oli oikea syy toimimattomuuteen, tuskin kuitenkaan se, ettei se tukisi HTTP 1.1:stä)
Juu, kyllä esimerkkisivullasi toimii molemilla versioilla.
Käyttämälläni sivulla ilman "versiointia" tai versiolla 1.1 tulee virheilmoitus:
The remote server returned an error: (417) Expectation Failed.
riville:
Dim Response As WebResponse = request.GetResponse().
Vaikkakin sivut antavat HTTP headeriin ensimmäiseksi seuraavan rivin:
esimerkkisivusi: GET /putka/novice/ HTTP/1.1
käyttämäni sivu: GET /fi/index.php HTTP/1.1
Eikös tuo nimenomaan kerro tuon versionumeron? Vai olenko taas kartanolla?
Veikkaisin, ettei nyt ole kyse tuosta versiosta vaan jostain datasta, jota palvelin 1.1-versiota käytettäessä odottaa ja jota ei jostain syystä tule. Pystytkö tarkistamaan, mitä muuta ohjelma lähettää ja mitä esimerkiksi normaali selain vastaavassa tilanteessa lähettää?
Heippa taas!
Rupesi jurppimaan tuo Grez'n hieno demo joten päätin yhdistää jutskan WebClient-luokkaan...
Imports System Imports System.IO Imports System.Net Imports System.Text Public Partial Class MainForm Public Sub New() Me.InitializeComponent() Me.Visible = False End Sub Sub MainFormLoad(sender As Object, e As EventArgs) Using client As New MyClient() client.HeadOnly = True Dim uri As String = "http://grez.info/putka/novice/" Dim body As Byte() = client.DownloadData(uri) Dim type As String = client.ResponseHeaders("content-type") client.HeadOnly = False If type.StartsWith("text/") Then Dim text As String = _ client.DownloadString(uri + "sisalto.php") msgbox(text) Me.Close End If End Using End Sub Class MyClient: Inherits WebClient Public Property HeadOnly() As Boolean Get End Get Set End Set End Property Private Cookies As New CookieContainer() Protected Overloads Overrides Function _ GetWebRequest(address As Uri) As WebRequest Dim request As WebRequest = _ MyBase.GetWebRequest(address) If HeadOnly AndAlso request.Method = "GET" Then request.Method = "HEAD" End If If TypeOf(request) Is HttpWebRequest Then TryCast(request, HttpWebRequest). _ CookieContainer = Cookies request.Method = "POST" request.ContentType = _ "application/x-www-form-urlencoded" Dim bytes() As Byte = _ Encoding.Default.GetBytes("user=novice&pass=ecivon") request.ContentLength = bytes.Length Dim oStream As Stream = _ request.GetRequestStream() oStream.Write(bytes, 0, bytes.Length) oStream.Close() End If Return request End Function End Class End Class
neau33 kirjoitti:
Rupesi jurppimaan tuo Grez'n hieno demo joten päätin yhdistää jutskan WebClient-luokkaan...
Mikäs siinä rupesi jurppimaan? Tuo lihavoimasi osako, vai oliko siinä muutakin vikaa?
No heippa taas!
@Grez: ei vaan se HIENO
Aihe on jo aika vanha, joten et voi enää vastata siihen.