C# 使用 WebClient 或 WebRequest 登录网站并访问数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17183703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using WebClient or WebRequest to login to a website and access data
提问by Shimmy Weitzhandler
I'm trying to access restricted data on a website using WebClient/WebRequest. There is no official API in that website, so what I'm trying to do is simply fill the HTML form and post the values to the server, so I'm logged in.
我正在尝试使用WebClient/访问网站上的受限数据WebRequest。该网站上没有官方 API,所以我要做的只是填写 HTML 表单并将值发布到服务器,因此我已登录。
I tried thisand this, but it doesn't look like the upcoming requests are logged in.
我尝试了this和this,但看起来没有登录即将到来的请求。
The latter example is much more appealing since I obviously prefer WebClient, but legacy WebRequestwill do.
后一个例子更吸引人,因为我显然更喜欢WebClient,但遗产WebRequest也可以。
Anyway, in the first example I think it did login, but the upcoming requests that access the private data return a page with a message "This is member only content".
无论如何,在第一个示例中,我认为它确实登录了,但是即将到来的访问私有数据的请求会返回一个带有消息“这是仅限会员的内容”的页面。
How to make a WebClientpermanently logged in?
如何进行WebClient永久登录?
采纳答案by Shimmy Weitzhandler
Update:
更新:
See my commentbelow.
Here's what I did and it works (credit).
这就是我所做的并且它有效(信用)。
Add this class first:
首先添加这个类:
namespace System.Net
{
using System.Collections.Specialized;
using System.Linq;
using System.Text;
public class CookieAwareWebClient : WebClient
{
public void Login(string loginPageAddress, NameValueCollection loginData)
{
CookieContainer container;
var request = (HttpWebRequest)WebRequest.Create(loginPageAddress);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var query = string.Join("&",
loginData.Cast<string>().Select(key => $"{key}={loginData[key]}"));
var buffer = Encoding.ASCII.GetBytes(query);
request.ContentLength = buffer.Length;
var requestStream = request.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
container = request.CookieContainer = new CookieContainer();
var response = request.GetResponse();
response.Close();
CookieContainer = container;
}
public CookieAwareWebClient(CookieContainer container)
{
CookieContainer = container;
}
public CookieAwareWebClient()
: this(new CookieContainer())
{ }
public CookieContainer CookieContainer { get; private set; }
protected override WebRequest GetWebRequest(Uri address)
{
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = CookieContainer;
return request;
}
}
}
Usage:
用法:
public static void Main()
{
var loginAddress = "www.mywebsite.com/login";
var loginData = new NameValueCollection
{
{ "username", "shimmy" },
{ "password", "mypassword" }
};
var client = new CookieAwareWebClient();
client.Login(loginAddress, loginData);
}
回答by Badri
HTTP is stateless. So, you cannot WebClient permanently logged in. The concept of a session does not exist in HTTP. The server-side technologies such as ASP.NET simulate a stateful behavior through the concept of session using cookie or a query string parameter that gets sent back and forth in every request. Having said that, it is possible to emulate what a browser does from WebClient. If you have access to the website, connect to it using the right credentials and capture the traffic using Fiddler. Then, make sure WebClient sends out the right cookies, request headers, query strings, etc exactly same as the browser.
HTTP 是无状态的。因此,您不能通过 WebClient 永久登录。 HTTP 中不存在会话的概念。服务器端技术(例如 ASP.NET)通过使用 cookie 或在每个请求中来回发送的查询字符串参数的会话概念来模拟有状态行为。话虽如此,可以从 WebClient 模拟浏览器所做的事情。如果您有权访问该网站,请使用正确的凭据连接到该网站并使用 Fiddler 捕获流量。然后,确保 WebClient 发送与浏览器完全相同的正确 cookie、请求标头、查询字符串等。

