vb.net Log into website - html

I am trying to log into Rueters.com through my VB.net program. So far my code works until I click the "Sign In" button. No errors occur, but it doesn't log in either. What am I doing wrong? Thanks in advance for any help.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("https://commerce.us.reuters.com/login/pages/login/login.do?backUrl=http%3A%2F%2Fwww.reuters.com%2F&backParameterEncoded=false&source=portfolio&flow=PORTFOLIO&entry_source=registration")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
WebBrowser1.Document.GetElementById("loginName").SetAttribute("value", "username")
WebBrowser1.Document.GetElementById("password").SetAttribute("value", "password")
Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
For Each webpageelement As HtmlElement In allelements
If webpageelement.GetAttribute("class") = "button" Then
webpageelement.InvokeMember("click")
End If
Next
End Sub
Sorry I forgot to include the HTML! Here it is:
<div class="label">
Email</div>
<div class="textfield">
<input type="text" size="40" maxlength="100" name="loginName" value="username" />
</div>
<div class="label">
Password</div>
<div class="textfield">
<input type="password" value="" size="40" maxlength="20" name="password" />
</div>
<div class="checkbox">
<input type="hidden" value="true" name="flag" />
<input type="checkbox" onclick="if(this.checked) this.form.flag.value='true'; else this.form.flag.value='false';" id="RememberCredentialsCBID" checked="checked" />
<label class="label" for="RememberCredentialsCBID">Remember me on this computer</label>
</div>
<div id="loginErr" class="label error">
</div>
<div class="submit">
<div class="button"><input type="image" src="/resources_v2/images/btn_sign_in.gif" />
</div>
</div>
<div class="textfield">
Forgot your password?
</div>
</form>

How about:
WebBrowser1.Document.GetElementById("loginName").SetAttribute("value", "username")
WebBrowser1.Document.GetElementById("password").SetAttribute("value", "password")
Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
For Each webpageelement As HtmlElement In allelements
If webpageelement.GetAttribute("type") = "image" Then
If webpageelement.GetAttribute("src") = "https://commerce.us.reuters.com/resources_v2/images/btn_sign_in.gif" Then
webpageelement.InvokeMember("click")
End If
End If
Next

Related

Html button not firing code in behind event

I am trying to get a simple form to post to my sql database, but nothing is happening when i click on it. I have tried runat="Server, onclick, onserverclick tags but nothing is happening.
I am new to html forms so dont know if i should have the button outside of the actual form to do this? any help is greatly appreciated
Below is the html code
<div class="register-content" ">
<form method="POST" class="margin-bottom-0">
<label class="control-label">Name <span class="text-danger">*</span></label>
<div class="row row-space-10">
<div class="col-md-6 m-b-15">
<input id="First_Text" type="text" class="form-control" placeholder="First name" required />
</div>
<div class="col-md-6 m-b-15" >
<input id="Last_Text" type="text" class="form-control" placeholder="Last name" required />
</div>
</div>
<label class="control-label">Email <span class="text-danger">*</span></label>
<div class="row m-b-15">
<div class="col-md-12">
<input id="Email_Text" type="text" class="form-control" placeholder="Email address" required />
</div>
</div>
<label class="control-label">Password <span class="text-danger">*</span></label>
<div class="row m-b-15">
<div class="col-md-12">
<input id="Pass_Text" type="password" class="form-control" placeholder="Password" required />
</div>
</div>
<div class="register-buttons">
<button runat="server" onserverclick="ValidateUser" type="button" class="btn btn-primary btn-block btn-lg">Sign Up</button>
</div>
<div class="m-t-20 m-b-40 p-b-40">
Already a registered user? Click here to login.
</div>
<hr />
<p class="text-center">
© NZAB All Right Reserved 2019
</p>
</form>
</div>
And here is the code behind
Protected Sub ValidateUser(sender As Object, e As EventArgs)
Dim connect As New SqlConnection(ConfigurationManager.ConnectionStrings("NZABFMAD_Users").ToString())
Using coa As New SqlCommand()
With coa
.Connection = connect
.CommandType = CommandType.Text
End With
Try
connect.Open()
Dim insertcmd As String
insertcmd = "INSERT INTO [New_User] (Username,[First name],[Last name],Email,Password) values (#User_Text,#First_Text,#Last_Text,#Email_Text,#Pass_Text)"
coa.CommandText = insertcmd
coa.Parameters.AddWithValue("#User_Text", Request.Form("User_Text"))
coa.Parameters.AddWithValue("#First_Text", Request.Form("First_Text"))
coa.Parameters.AddWithValue("#Last_Text", Request.Form("Last_Text"))
coa.Parameters.AddWithValue("#Email_Text", Request.Form("Email_Text"))
coa.Parameters.AddWithValue("#Pass_Text", Request.Form("Pass_Text"))
coa.ExecuteNonQuery()
connect.Close()
MsgBox("success insert")
Catch ex As Exception
MsgBox("Fail to Save to database")
End Try
End Using
End Sub
Granted i will be salting/hashing passwords when storing in sql, but for now i just want the button to actually fire the event!
First of all you need to give each input field a name, as that is what identifies them when posted to the server. The id is merely for client-side identification (e.g. via JavaScript).
<input id="First_Text" name="First_Text" type="text" class="form-control" placeholder="First name" required />
Secondly, the button merely calls the callback on the server. It doesn't actually submit the form, so in this case Request.Form will be empty.
For standard HTML forms you need to use an <input type="submit"/> so that your form is actually submitted and its data sent to the server. You can then invoke the reading of its data from the Page_Load handler.
<div class="register-buttons">
<input type="submit" class="btn btn-primary btn-block btn-lg" value="Sign up"/>
</div>
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Check if this is a POST request.
If HttpContext.Current.Request.HttpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase) Then
DoSignUp()
End If
End Sub
Private Sub DoSignUp()
'Put your code from ValidateUser here.
End Sub
Although you could, like Andrew Morton said in the comments, replace the form and your input fields with ASP.NET controls and handle it via postback instead. I'm not sure which method is preferred in this case as I haven't worked much with WebForms. Personally, I'd use a form like you do now.

Trying to fill in a form to login to a site via VBA but wont register the text I've entered

First time poster, long time user.
I'm trying to write a script in VBA to login to a site to then extract data at a later step.
I've hit a road block with trying to logon to the site, there is three classes that change once you manually fill in the username and password and two aria-invalid that turn from true to false. Unfortunately, this doesn't update if you try and fill in the forms via VBA.
This is the VBA code I currently have
Option Explicit
Sub LoginToSite()
Dim IE As New SHDocVw.InternetExplorer
IE.Visible = True
IE.navigate "https://website.com.au"
Do While IE.ReadyState <> READYSTATE_COMPLETE
Loop
IE.Document.forms("form").elements("username").Value = "FredFlinstone"
IE.Document.forms("form").elements("password").Value = "Password000"
IE.Document.forms("form").elements("submit-button").Click
End Sub
This is the HTML before manual text is added into the forms:
`<form name="form" class="login-form ng-pristine ng-invalid ng-invalid-required" novalidate="" autocomplete="off">
<div class="field-container">
<label for="username">
Username
</label>
<input name="username" class="ng-pristine ng-empty ng-invalid ng-invalid-required ng-touched" id="username" aria-invalid="true" required="" type="text" ng-keydown="vm.loginOnKeyEnter($event)" ng-class="vm.usernameEmptyClass" ng-model="vm.username">
</div>
<div class="field-container ">
<label for="password">
Password
</label>
<input name="password" class="ng-pristine ng-untouched ng-empty ng-invalid ng-invalid-required" id="password" aria-invalid="true" required="" type="password" ng-keydown="vm.loginOnKeyEnter($event)" ng-class="vm.passwordEmptyClass" ng-model="vm.password">`
These are the parts that change in the HTML if you manually add text.
Form div
<form name="form"
class="login-form ng-dirty ng-valid-parse ng-valid ng-valid-required"
novalidate=""
autocomplete="off">
Username Div
<input name="username"
class="ng-touched ng-not-empty ng-dirty ng-valid-parse ng-valid ng-valid-required"
id="username"
aria-invalid="false"
required=""
type="text"
ng-keydown="vm.loginOnKeyEnter($event)"
ng-class="vm.usernameEmptyClass"
ng-model="vm.username">
Password Div
<input name="password"
class="ng-not-empty ng-dirty ng-valid-parse ng-valid ng-valid-required ng-touched"
id="password"
aria-invalid="false"
required=""
type="password"
ng-keydown="vm.loginOnKeyEnter($event)"
ng-class="vm.passwordEmptyClass"
ng-model="vm.password">
Very keen to learn what I need to change in order to trigger the site into realising there is text within the boxes to be able to login.
I've still got my L plates on with VBA, so code will most definitely not be the most efficient code, but keen to hear of better methods to executing the above
Thanks in advance Mr Swan
Try to use the .Focus method to focus the TextBox first, then use the SendKeys statement to enter the value.
The below code should work if it's single page but you'll have to fill out the SignIn Div information portion since this doesn't appear to be a valid URL. Just follow the same format and note that everything is case sensitive. TKs.
Sub LoginToSite()
Const cURL = "https://website.com.au"
Const cusername = "FredFlinstone"
Const cpassword = "Password000"
Dim IE As InternetExplorer
Dim doc As HTMLDocument
Dim LoginForm As HTMLFormElement
Dim UsernameInputBox As HTMLInputElement
Dim PasswordInputBox As HTMLInputElement
Dim SigninButton As HTMLInputButtonElement
Set IE = New InternetExplorer
IE.Visible = True
IE.navigate cURL
'Wait for initial page to load
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
Set doc = IE.document
'Get the only form on the page
Set LoginForm = doc.forms(0)
'Get the Username textbox and populate it
'input name="username" id="username" size="18" value="" class="ng-touched ng-not-empty ng-dirty ng-valid-parse ng-valid ng-valid-required" type="text"
Set UsernameInputBox = doc.getElementById("username")
UsernameInputBox.Value = cusername
'Get the Password textbox and populate it
'input name="password" id="password" size="18" class="ng-not-empty ng-dirty ng-valid-parse ng-valid ng-valid-required ng-touched" type="text"
Set PasswordInputBox = doc.getElementById("password")
PasswordInputBox.Value = cpassword
'Get the form input button and click it
'button class="XXXXX" name="XXXXX" id="XXXXX" value="XXXXX" type="text"
Set SigninButton = doc.getElementById("XXXXX")
SigninButton.Click
'Wait for the new page to load
Do While IE.readyState <> READYSTATE_COMPLETE Or IE.Busy: DoEvents: Loop
End Sub
Is everything on one page or is it split between two pages like the Gmail login?
1 page example: enter username, enter password, click login
2 page example: enter username (click next), enter password, click login

Login to website VBA yields error when changing Name

I found here a code that actually input login data and login to website. It works on that website (so references are turned on correctly) - Login to a website using VBA . I am trying to use that in a company but I get an error when I adjust the names.
Am I doing something wrong?
Error:
Run-time error 438
Object doesnt support this property or method.
It appears at line "oLogin.Value = UserName"
Sub login()
Const Url$ = "site.company.org"
Dim UserName As String, Password As String, LoginData As Worksheet
Set LoginData = ThisWorkbook.Worksheets("Sheet1")
UserName = LoginData.Cells(1, "B").Value
Password = LoginData.Cells(2, "B").Value
Dim ie As Object
Set ie = CreateObject("InternetExplorer.Application")
With ie
.navigate Url
ieBusy ie
.Visible = True
Dim oLogin As Object, oPassword As Object
Set oLogin = .document.getElementsByName("login")(0)
Set oPassword = .document.getElementsByName("heslo")(0)
oLogin.Value = UserName
oPassword.Value = Password
.document.forms(0).submit
End With
End Sub
Sub ieBusy(ie As Object)
Do While ie.Busy Or ie.readyState < 4
DoEvents
Loop
End Sub
Here is HTML for my website
<form name="login" method="post" enctype="multipart/form-data" action="./index.php?page=main/login.php">
<input type="hidden" name="chyba" value="">
<input type="hidden" name="odeslano" value="1">
<input type="hidden" name="redir_url" value="http://zinfo.kamax.org/">
<table align="left" class="NORMAL left">
<tbody><tr>
<td align="right">*Login:</td>
<td align="left"><input class="polozka_formulare_req" type="text" name="login" size="20" maxlength="20" value="" autofocus="autofocus"></td>
</tr>
<tr>
<td align="right">*Password:</td>
<td align="left"><input class="polozka_formulare_req" type="password" name="heslo" size="12" maxlength="12" value=""></td>
</tr>
<tr>
<td align="right"></td>
<td align="center">
<br>
<input type="submit" name="submit" value="Log In" class="TLAC">
<!--<button class="TLAC" type="button" onClick="window.open('//website.company.org/','_self');return false;">Back</button>-->
</td>
</tr>
</tbody></table>
<div class="login_warn">
Important Note to all Users:
<br><br>
All Documents in this system are for company internal use only.
Forwarding of any document or even parts of it to external parties without prior approval by QM or RD is strictly prohibited.
</div>
</form>
You could target the input boxes. As noted you would need to handle frames/iframes first if they are present.
ie.document.querySelector("input[name=login]").Value ="n"
ie.document.querySelector("input[type=password]").Value ="x"
Instead of trying to use an oLogin generic object, try referencing the webform directly like this:
ie.Document.ALL.login.Value = UserName
ie.Document.ALL.heslo.Value = Password

getElementById where the id changes randomly

I am trying to automate a website login for:
https://www.check-mot.service.gov.uk/
However the ID of the input textbox changes randomly, is there a way to scan through the code and establish it's current ID?
I have tried using GetElementsByTagName but that did not work.
When I use the inspect element it takes me to this line:
It is the 202413237510 that changes randomly of the line of code below.
<input name="202413237510" class="form-control" id="202413237510" type="text" value="">
The surrounding code below:
<form name="moth-search" id="EVL" action="/" method="POST">
<fieldset>
<legend class="form-title heading-medium visuallyhidden">Enter the vehicle registration</legend>
<input name="_csrf_token" type="hidden" value="7A9313B6-6834-04E2-56BE-D6966FFE041F">
<div class="form-group apiary-22453 ddt">
<label class="form-label form-label-bold" for="1700806253">
<span>Do not fill this field</span>
<span class="form-hint">For example, CU57ABC</span>
</label>
<input name="1700806253" tabindex="-1" class="form-control" id="1700806253" type="text" value="">
</div>
<div class="form-group is-on-show tyu-33">
<label class="form-label form-label-bold" for="reg-number">
<span>Do not enter anything in this field</span>
<span class="form-hint">For example, CU57ABC</span>
</label>
<input name="reg-number" tabindex="-1" class="form-control" id="reg-number" type="text" value="">
</div>
<div class="form-group hoth-field it-290">
<label class="form-label form-label-bold" for="202413237510">
<span><span class="sr-only">Enter your</span> Registration number (number plate) <span class="sr-only">into this field only</span></span>
<span class="form-hint">For example, CU57ABC</span>
</label>
<input name="202413237510" class="form-control" id="202413237510" type="text" value="">
</div>
<div class="form-group it-290 salad-box">
<label class="form-label form-label-bold" for="vehicle-manufacturer">
<span>This field should be left empty</span>
<span class="form-hint">For example, CU57ABC</span>
</label>
<input name="vehicle-manufacturer" tabindex="-1" class="form-control" id="vehicle-manufacturer" type="text" value="">
</div>
<div class="form-group keep-hidden isOnshow">
<label class="form-label form-label-bold" for="registration">
<span>Do not fill this field</span>
<span class="form-hint">For example, CU57ABC</span>
</label>
<input name="registration" tabindex="-1" class="form-control" id="registration" type="text" value="">
</div>
<div class="form-group bee-hive tyu-33">
<label class="form-label form-label-bold" for="registration-number">
<span>Do not fill this field</span>
<span class="form-hint">For example, CU57ABC</span>
</label>
<input name="registration-number" tabindex="-1" class="form-control" id="registration-number" type="text" value="">
</div>
You don't show any code so I'm not sure how you're getting at the document. My example uses the IE object from MS Internet Controls and then RegExp object from VBScript Regular Expressions.
You should be able to just pull out the RegExp constant, variables and code to get your id from your document body variable.
This regular expression searches for matching input elements that consist of numbers in the their name - but the trick is it ignores the ones that have tabindex="-1" in the definition.
Sub ExtractID()
'To use this example you'll need two references
'Open the VBA editor and pull down Tools | References menu
'- select "Microsoft Internet Controls"
'- select "Microsoft VBScript Regular Expressions 5.5"
Const FIND_NEW_ID As String = "name=""(\d)*"" class=""form-control"" id=""(\d)*"""
Dim ie As SHDocVw.InternetExplorer
Dim regEx As New RegExp
Dim idMatches As MatchCollection
Dim idMatch As Match
Dim strHTML As String
Dim strID As String
Set ie = New SHDocVw.InternetExplorer
With ie
.Navigate "https://www.check-mot.service.gov.uk/"
Do While .ReadyState <> READYSTATE_COMPLETE Or .Busy = True
DoEvents
Loop
strHTML = ie.Document.body.innerHTML
'Set doc = .Document
'strHTML = doc.body.innerHTML
With regEx
.Global = True
.Multiline = True
.IgnoreCase = False
.Pattern = FIND_NEW_ID
End With
If regEx.Test(strHTML) Then
Set idMatches = regEx.Execute(strHTML)
If idMatches.Count = 1 Then
strID = Mid$(idMatches(0).Value, 7) ' remove name from front
strID = Left$(strID, InStr(strID, """") - 1) ' pull ID from double quotes
MsgBox "Found ID: " & strID
Else
MsgBox "Not Going to Work - we found multiples"
End If
Else
MsgBox ("No ID Found")
End If
End With
End Sub
Regex101.com is a great site for testing regular expressions against your HTML docs

VB.Net , Can't click button, No ID or Name

I am trying to get a balance checker for Adnooka, but I can't even get past the login.
Here's the HTML:
</div>
<div class="control-group row-fluid">
<label class="row-fluid " for="inputPassword">Password <div class="pull-right"><a class="muted"><small><a href='http://adnooka.com/recover'>Forgot your password ?</a></small></a></div></label>
<div class="controls row-fluid input-append">
<input type="password" id="inputPassword" placeholder="Password" name="password" class="row-fluid" value=""> <span class="add-on"><i class="icon-lock"></i></span>
</div>
</div>
<div class="control-group row-fluid fluid">
<div class="controls span6">
</div>
<div class="controls span5 offset1" style=''>
<button type='submit' class="btn btn-default" style='float:right'>Login<i class="gicon-chevron-right"></i></a>
</div>
</div>
But the Button has no ID or Name, how can I click it?
How how can I return the value of a balance?
Here's what I've got so far:
WebBrowser1.Document.GetElementById("email").SetAttribute("value", textbox1.Text)
WebBrowser1.Document.GetElementById("password").SetAttribute("value", pass.Text)
Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
For Each webpageelement As HtmlElement In allelements
If webpageelement.GetAttribute("type") = "submit" Then
webpageelement.InvokeMember("click")
End If
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebBrowser1.Navigate("http://adnooka.com/login")
End Sub
You can invoke a submit on the form itself, you don't have to find a button to click.
This should work, if you have only one form on the page. If not, adjust the [0] to whatever is needed:
WebBrowser1.Document.Forms[0].InvokeMember("submit")
See http://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument.forms.aspx for more details.