所以我试图使用httpwebrequest登录到一个网站。我从http调试器获得的发布数据是
我正在尝试的代码是:
Dim postData As String = "securitycheck=85b39cc89f04bc1612ce9d0c384b39ca&do_action=log_into_system&jump_to=https%3A%2F%2Fwww.dreamstime.com%2F&uname=jawademail&pass=jawadpass"
Dim tempCookies As New CookieContainer
Dim encoding As New UTF8Encoding
Dim byteData As Byte() = encoding.GetBytes(postData)
Dim postReq As HttpWebRequest = DirectCast(WebRequest.Create("https://www.dreamstime.com/securelogin.php"), HttpWebRequest)
postReq.Method = "POST"
postReq.KeepAlive = True
postReq.CookieContainer = tempCookies
postReq.ContentType = "application/x-www-form-urlencoded"
postReq.Referer = "https://www.dreamstime.com/login.php"
postReq.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
postReq.ContentLength = byteData.Length
Dim postreqstream As Stream = postReq.GetRequestStream()
postreqstream.Write(byteData, 0, byteData.Length)
postreqstream.Close()
Dim postresponse As HttpWebResponse
postresponse = DirectCast(postReq.GetResponse(), HttpWebResponse)
tempCookies.Add(postresponse.Cookies)
logincookie = tempCookies
Dim postreqreader As New StreamReader(postresponse.GetResponseStream())
Dim thepage As String = postreqreader.ReadToEnd
RichTextBox1.Text = thepage
该代码似乎未在网站中发布数据,运行代码后,我在richtextbox中获得了引用页面代码。
答案 0 :(得分:1)
我自己看了一下,看来每次登录请求都会发送一个令牌来标识您的“会话”,具体来说:
<h2><b>Λίστα Προϊόντων</b></h2> <!-- We set the heading of the HTML Table. -->
<div id="jsGrid"> <!-- We add a "<div>" for the grid. -->
<table style="width:100%;">
<thead> <!-- We group the "header" content in the HTML Table. -->
<tr> <!-- The "header" content of the HTML Table is not repeated. -->
<th>Κατηγορία</th>
<th>Περιγραφή</th>
<th>Λεπτομέρειες</th>
<th style="width:75px;">Τιμή (€)</th>
<th></th>
</tr>
</thead>
<tbody ng-repeat="x in product track by $index"> <!-- The HTML Table is populated from the JSON Array "product", using a "ng-repeat" directive which is assigned to each row of the Table in order to repeat all the objects of the Array. -->
<tr> <!-- Each row of the HTML Table consists of 4 HTML fields and 1 button. -->
<td><input type="text" value="{{x.Category}}" /></td>
<td style="width:100%; padding:0px 8px 0px 0px"><input style="width:100%;" type="text" value="{{x.Description}}" /></td>
<td><input type="text" value="{{x.Details}}" /></td>
<td><input style="width:75px;" type="number" value="{{x.Price}}" /></td>
<td><input type="button" ng-click="removeProduct($index)" value="Remove" /></td> <!-- The "ng-click" directive is assigned to the "Remove" button and calls the function named "removeProduct" with the current "$index" when this button is clicked. -->
</tr>
</tbody>
</table>
</div>
<hr> <!-- We separate the HTML content of the page. -->
<div>
<h2><b>Καταχώρησε νέο προϊόν</b></h2> <!-- We set the heading of the HTML Form. -->
<div class="row"> <!-- We set the "1st row" of the HTML Form. -->
<div class="col-md-6"> <!-- We use "md" for "medium" screen devices of width "equal to or greater than" 992px and "6" for adding 6 columns. -->
<div class="form-group"> <!-- We use "form-group" for optimum spacing. -->
<label class="control-label" for="category">Επίλεξε Κατηγορία:</label>
<div class="controls">
<input list="category" name="categories" ng-model="Category" /> <!-- When the value of the input field "Επίλεξε Κατηγορία" changes, is bound to the created variable "Category" in AngularJS by the "ng-model" directive. -->
<datalist id="category">
<option value="Desktop">
<option value="Laptop">
<option value="Tablet">
<option value="Οθόνη Υπολογιστή">
<option value="Οθόνη Προβολής">
<option value="Εκτυπωτής laser">
<option value="Φωτοτυπικό Μηχάνημα">
<option value="Scanner">
<option value="UPS">
<option value="Διαδικτυακή Συσκευή Αποθήκευσης">
<option value="Εξωτερικός Σκληρός Δίσκος">
<option value="Προτζέκτορας">
<option value="Βιντεοπροτζέκτορας">
</datalist>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label" for="description">Περιγραφή</label>
<div class="controls">
<input id="description" type="text" onkeypress="this.style.width = ((this.value.length + 1) * 8) + 'px';" ng-model="Description" /> <!-- When the value of the input field "Περιγραφή" changes, is bound to the created variable "Description" in AngularJS by the "ng-model" directive. -->
</div>
</div>
<div class="form-group">
<label class="control-label" for="details">Λεπτομέρειες</label>
<div class="controls">
<input id="details"
type="file"
cam-variable-name="Details"
cam-variable-type="File"
cam-max-filesize="10000000" ng-model="Details" /> <!-- When the value of the input field "Λεπτομέρειες" changes, is bound to the created variable "Details" in AngularJS by the "ng-model" directive. -->
</div>
</div>
<div class="form-group">
<label class="control-label" for="price">Τιμή (€)</label>
<div class="controls">
<input style="width:75px;" id="price" type="number" min="0" ng-model="Price" /> <!-- When the value of the input field "Τιμή (€)" changes, is bound to the created variable "Price" in AngularJS by the "ng-model" directive. -->
</div>
</div>
<div class="controls">
<input type="button" ng-click="addProduct();clear()" ng-show="isAddFormValid()" value="Add" /> <!-- The "ng-show" directive shows the input element ("Add" button) only if the "isAddFormValid()" function (expression) returns "true". The "ng-click" directive is assigned to the "Add" button and calls the functions named "addProduct()" and "clear()" when this button is clicked. -->
</div>
</div>
</div>
</div>
</form>
</body>
</html>
每次登录时此令牌都会更改,如果该令牌无效,则站点会将您重定向到登录页面,要求您再次登录。
网站通常这样做是为了防止Cross-Site Request Forgery (CSRF)。这意味着您很可能将无法使用实际的Web浏览器 登录该网站。
答案 1 :(得分:1)
这是经过测试的代码,它可以正常工作。它使用System.Net.Http.HttpClient而不是WebClient(因为它支持并发请求)。该代码 只是一个模型 ,因为其主要目的是展示如何使用此网站的想法。注释中还有其他解释。您还需要导入System.Web
dll。
Imports System.Net.Http
Imports System.Web
Imports System.Text.RegularExpressions
Public Class TestForm
Private Const URL_MAIN$ = "https://www.dreamstime.com"
Private Const URL_LOGIN$ = "https://www.dreamstime.com/securelogin.php"
Private Const URL_LOGOUT$ = "https://www.dreamstime.com/logout.php "
Private Const USER_AGENT$ = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
"AppleWebKit/537.36 (KHTML, Like Gecko) " +
"Chrome/68.0.3440.15 Safari/537.36 OPR/55.0.2991.0 " +
"(Edition developer)"
Private Const LOGIN$ = "<USER_NAME>"
Private Const PASS$ = "<USER_PASSWORD>"
Private token$
Private Async Sub OnGo() Handles btnGo.Click
Dim html$
Using client = New HttpClient()
client.DefaultRequestHeaders.Add("User-Agent", USER_AGENT)
Using req = New HttpRequestMessage(HttpMethod.Get, URL_MAIN)
Using resp = Await client.SendAsync(req)
html = Await resp.Content.ReadAsStringAsync()
End Using
End Using
'// Search for security token
Dim m = Regex.Match(
html,
"<input type=""hidden"" name=""securitycheck"" value=""(?'token'\w+)"">")
If Not m.Success Then
MessageBox.Show("Could not find security token.")
Return
End If
'// Get security token
token = m.Groups("token").Value
'// Try to login.
'// For logging to work, we need to use FormUrlEncodedContent class.
'// Also we need to use it every time we do POST requests.
'// No need for it for GET requests (as long as the HttpClient is the same).
Using req = New HttpRequestMessage(HttpMethod.Post, URL_LOGIN) With
{
.Content = GetFormData()
}
Using resp = Await client.SendAsync(req)
html = Await resp.Content.ReadAsStringAsync()
End Using
End Using
'// Go to main page to check we're logged in.
'// "html" variable now MUST contain user's account name.
Using req = New HttpRequestMessage(HttpMethod.Get, URL_MAIN$)
Using resp = Await client.SendAsync(req)
html = Await resp.Content.ReadAsStringAsync()
End Using
End Using
'// Logout.
'// "html" variable now MUST NOT contain user's account name.
Using req = New HttpRequestMessage(HttpMethod.Get, URL_LOGOUT)
Using resp = Await client.SendAsync(req)
html = Await resp.Content.ReadAsStringAsync()
End Using
End Using
End Using
End Sub
Function GetFormData() As FormUrlEncodedContent
Return New FormUrlEncodedContent(New Dictionary(Of String, String) From
{
{"securitycheck", token},
{"do_action", "log_into_system"},
{"jump_to", ""},
{"uname", HttpUtility.HtmlEncode(LOGIN)},
{"pass", HttpUtility.HtmlEncode(PASS)}
})
End Function
End Class
答案 2 :(得分:1)
首先获取页面,在其源代码中找到“安全检查”并将其解压缩。
将其与其余数据合并,然后通过POST发送。
好,所以我想尝试:
Dim LoginData As String
Dim LoginCookies As New CookieContainer() 'Move this outside of sub/function so you can use it later
Dim LoginRequest As HttpWebRequest = WebRequest.Create("https://www.dreamstime.com/login.php")
LoginRequest.CookieContainer = LoginCookies
LoginRequest.KeepAlive = True
LoginRequest.AllowAutoRedirect = True
LoginRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"
Dim LoginResponse As HttpWebResponse = LoginRequest.GetResponse()
Dim LoginResponseRead As StreamReader = New StreamReader(LoginResponse.GetResponseStream())
Using LoginResponseRead
Do
Dim line As String = LoginResponseRead.ReadLine
If line.Contains("var securitycheck=") Then
LoginData = "securitycheck=" & line.Substring(line.IndexOf("=") + 2, line.LastIndexOf("'") - line.IndexOf("=") - 2)
Exit Do
End If
Loop
End Using
Dim byteData As Byte() = Encoding.UTF8.GetBytes(LoginData)
LoginRequest = WebRequest.Create("https://www.dreamstime.com/securelogin.php")
LoginRequest.CookieContainer = LoginCookies
LoginRequest.Method = "POST"
LoginRequest.KeepAlive = True
LoginRequest.ContentType = "application/x-www-form-urlencoded"
LoginRequest.Referer = "https://www.dreamstime.com/login.php"
LoginRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
LoginRequest.ContentLength = byteData.Length
Dim postreqstream As Stream = LoginRequest.GetRequestStream()
postreqstream.Write(byteData, 0, byteData.Length)
postreqstream.Close()
LoginResponse = LoginRequest.GetResponse()
LoginResponseRead = New StreamReader(LoginResponse.GetResponseStream())
Dim thepage As String = LoginResponseRead.ReadToEnd
'Now with GET request grab whatever you want, DON'T forget to use cookie.
结果
>>>securitycheck=183d5abdb01f288aacbe5b2893555ec5
Dim email As String = "something"
Dim password As String = "somethingelse"
LoginData &= "&do_action=log_into_system&jump_to=https%3A%2F%2Fwww.dreamstime.com%2F&uname=" & email & "&pass=" & password
>>>securitycheck=183d5abdb01f288aacbe5b2893555ec5&do_action=log_into_system&jump_to=https%3A%2F%2Fwww.dreamstime.com%2F&uname=something&pass=somethingelse
实际上完成了。