好的,所以我正在编写一个需要登录网站的程序,希望从中获取一些信息。
他是我登录的代码:
module Webscraper =
open System.Net
open HtmlAgilityPack
open Lolcr.Model
open System.Collections.Specialized
let logon = fun (address:string) studentNumber password->
let upload values =
let wc = new WebClient()
wc.UploadValues (address, values)
let ToNameValueCollection nvs =
let col = new NameValueCollection()
for nv in nvs do
match nv with (n, v) -> col.Add(n, v);
col
let fields :List<string*string> =
("v_studentid",studentNumber) ::
("v_studentpin", password) ::
("b3", "Login") :: []
let resp = fields |> ToNameValueCollection |> upload;
resp |> Array.map char |> System.String.Concat
//and for viewing a page within the site:
let pageAt = fun (address : string) ->
let getWebStream =
let req = HttpWebRequest.Create address
let resp = req.GetResponse()
resp.GetResponseStream
let doc = new HtmlDocument()
getWebStream() |> doc.Load;
doc.DocumentNode
现在当我调用logon时,它会返回登录页面的文本,好像我还没有登录(可能登录后会在浏览器中完成重定向) 当我在页面上调用PageAt时,我感兴趣的是重新调整“请登录”页面。
看看Fiddler2发生了什么:(其中XXXX和YYYY分别是studentNumber和密码):
//Via firefox
POST https://server2.olcr.uwa.edu.au/olcrstudent/index.jsp HTTP/1.1
Host: server2.olcr.uwa.edu.au
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: https://server2.olcr.uwa.edu.au/olcrstudent/
Cookie: JSESSIONID=18F87DFEB1555A6FA644215FDAE5E506; __utma=55889711.14817822.1328281214.1328281214.1328281214.1; __utmz=55889711.1328281214.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=olcr%20uwa; __utmb=55889711.1.10.1328281214; __utmc=55889711
Content-Type: application/x-www-form-urlencoded
Content-Length: 53
v_studentid=XXXX&v_studentpin=YYYY&b3=Login
//From my program:
POST https://server2.olcr.uwa.edu.au/olcrstudent/index.jsp HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: server2.olcr.uwa.edu.au
Content-Length: 53
Expect: 100-continue
Connection: Keep-Alive
v_studentid=XXXX&v_studentpin=YYYY&b3=Login
所以我看到它的最大区别在于我没有发送任何cookie (我实际上并不完全确定饼干是什么,想到它(我会看起来那样)(编辑:完成)))
我应该发送cookies吗? 在.net中有什么机制? 我应该做一些不同的因素这是HTTPS吗?
答案 0 :(得分:1)
一般来说,当您登录网站时,您必须有一些方法让网站在页面之间进行跟踪。
通常使用cookie或URL中的会话标识符来完成。
现在,您需要了解两种类型的Cookie之间的区别。
一个是会话cookie,它在客户端计算机上保留在内存中,然后在您关闭浏览器(或会话关闭)后消失。这些仅包含引用服务器上的用户唯一会话实例的唯一标识符。这允许服务器在每个子序列页面命中时知道你是谁。
另一种类型的cookie是一个物理cookie,您可以将其特定设置为将特定变量保存在客户端计算机上的文本文件中。
如果您查看自己的回复,则会引用会话ID,这意味着您在客户端计算机上有会话Cookie:
Cookie: JSESSIONID=18F87DFEB1555A6FA644215FDAE5E506; __utma=55889711.14817822.1328281214.1328281214.1328281214.1; __utmz=55889711.1328281214.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=olcr%20uwa; __utmb=55889711.1.10.1328281214; __utmc=55889711
如果你曾经使用过session,那么这个cookie在asp.net中是默认创建的。
答案 1 :(得分:0)
是的,通常您需要持久cookie才能登录网站。 CookieAwareWebclient,例如来自this blog的CookieAware, 让它变得简单。 F#equivelent是
type CookieAwareWebclient (cookies) =
inherit WebClient()
member this.CookieContainer = cookies
new () = new CookieAwareWebclient(new CookieContainer())
override this.GetWebRequest (address:Uri) =
let req = base.GetWebRequest address
match req with
| :? HttpWebRequest as httpReq ->
httpReq.CookieContainer <- this.CookieContainer;
upcast httpReq
| _ -> req;
现在,只要你通过相同的 Webclient完成所有的webrequests(因此你必须让整个模块中的webclient可访问,并更改pageAt以使用它) 你会没事的