Problems submitting a login form with Jsoup
Besides the username
, password
and the cookies
, the site requeires two additional values for the login - VIEWSTATE
and EVENTVALIDATION
.
You can get them from the response of the first Get
request, like this -
Document doc = loginForm.parse();
Element e = doc.select("input[id=__VIEWSTATE]").first();
String viewState = e.attr("value");
e = doc.select("input[id=__EVENTVALIDATION]").first();
String eventValidation = e.attr("value");
And add it after the password
(the order doesn't really matter) -
org.jsoup.nodes.Document document = (org.jsoup.nodes.Document) Jsoup.connect("https://www.capitaliq.com/CIQDotNet/Login.aspx/authentication.php").userAgent("Mozilla/5.0")
.data("myLogin$myUsername", "MyUsername")
.data("myLogin$myPassword, "MyPassword")
.data("myLogin$myLoginButton.x", "22")
.data("myLogin$myLoginButton.y", "8")
.data("__VIEWSTATE", viewState)
.data("__EVENTVALIDATION", eventValidation)
.cookies(loginForm.cookies())
.post();
I would also add the userAgent
field to both requests - some sites test it and send different pages to different clients, so if you would like to get the same response as you get with your browser, add to the requests .userAgent("Mozilla/5.0")
(or whatever browser you're using).
Edit
The userName
's field name is myLogin$myUsername
, the password is myLogin$myPassword
and the Post
request also contains data about the login button. Ican't test it, because I don't have user at that site, but I believe it will work. Hope this solves your problem.
EDIT 2
To enable the remember me
field during login, add this line to the post
request:
.data("myLogin$myEnableAutoLogin", "on")
Login using Jsoup
Few remarks:
- You're getting HTTP status 302. It may be a good idea to use
Jsoup.connect(...).followRedirects(true)
- Some servers check the site you're coming from so it's recommened to set referrer header:
Jsoup.connect(...).referrer(URL + "/login")
- Are you sure the
hidden
value is always69
? Maybe it's different for each request. You can get it dynamically like this:formData.put("hidden",html.select("co_js").first().attr("value"));
I don't like your way of getting the token. Let's use Jsoup to extract it:
String authToken = html.select("input#token").first().attr("value");
Edit:
- I tried to do this from scratch and submitted login form was missing Content-Type definition. Try using:
Jsoup.connect(...).header("Content-Type","application/x-www-form-urlencoded")
I got the idea by analyzing headers in Chrome's dev tools. Now I can successfully login. - You can also check if you're logged in using this code:
Document doc = homePage.parse();
System.out.println("Logged in as: " + doc.select(".dropdown-toggle").text()); By letting server know you can handle compressed pages you can decrease downloaded page size. For every request use:
Jsoup.connect(...).header("accept-encoding", "gzip, deflate")
It's transparent and you don't have to do anything special to handle it, but it works internally.Edit 2:
Providing final solution based on previous advices:
import java.util.HashMap;
import java.util.Map;
import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class Stackoverflow51734840 {
private static final String URL = "https://time2watch.in";
private static final String URL_LOGIN = URL + "/login/";
static String userAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36";
public static void main(final String[] args) throws Exception {
Map<String, String> headers = new HashMap<String, String>();
headers.put("accept-encoding", "gzip, deflate");
Connection.Response loginForm = Jsoup.connect(URL + "/login").userAgent(userAgent).headers(headers).execute();
Map<String, String> cookies = loginForm.cookies();
Document html = loginForm.parse();
String authToken = html.select("input#token").first().attr("value");
System.out.println("Found authToken:" + authToken);
Map<String, String> formData = new HashMap<String, String>();
formData.put("username", "!!!!!!!!!!!!!!!!!!");
formData.put("pwd", "!!!!!!!!!!!!!!!!!!");
formData.put("hidden", "69");
formData.put("token", authToken);
headers.put("Content-Type", "application/x-www-form-urlencoded");
System.out.println("cookies before login:");
System.out.println(cookies);
System.out.println(" Logged in cookie present? " + cookies.containsKey("s4icookuser"));
Connection.Response afterLoginPage = Jsoup.connect(URL_LOGIN).cookies(cookies).headers(headers)
.userAgent(userAgent).data(formData).method(Connection.Method.POST).referrer(URL_LOGIN).execute();
// update cookies
cookies = afterLoginPage.cookies();
System.out.println("cookies after login:");
System.out.println(cookies);
System.out.println(" Logged in cookie present? " + cookies.containsKey("s4icookuser"));
Response homePage = Jsoup.connect(URL).cookies(cookies).method(Connection.Method.GET).userAgent(userAgent)
.referrer(URL_LOGIN).followRedirects(true).referrer(URL_LOGIN).headers(headers).execute();
Document doc = homePage.parse();
System.out.println("Error? " + doc.text().contains("Erreur"));
System.out.println("OK? " + !doc.text().contains("Se connecter"));
System.out.println("Logged in as: " + doc.select(".dropdown-toggle").text());
}
}
How to post form login using jsoup?
The URL that are you using in order to do the POST request is wrong, simply because when you have to do a specific request to a form you should use the web page that is present in the form tag, in this case "authentication.php".
So the code will be:
package jsouptest;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
public class JsouptTest {
public static void main(String[] args) throws Exception {
Connection.Response loginForm = Jsoup.connect("https://www.desco.org.bd/ebill/login.php")
.method(Connection.Method.GET)
.execute();
Document document = Jsoup.connect("https://www.desco.org.bd/ebill/authentication.php")
.data("cookieexists", "false")
.data("username", "32007702")
.data("login", "Login")
.cookies(loginForm.cookies())
.post();
System.out.println(document);
}
}
This one correctly retrieves the web page that you want.
Related Topics
Why Am I Getting a Noclassdeffounderror in Java
Java String to Date Conversion
How to Round a Number to N Decimal Places in Java
How to Create an Executable Jar With Dependencies Using Maven
How to Use Java.Net.Urlconnection to Fire and Handle Http Requests
Why Use Getters and Setters/Accessors
Difference Between Public, Protected, Package-Private and Private in Java
Non-Static Variable Cannot Be Referenced from a Static Context
Sort a Map≪Key, Value≫ by Values
Swing Gui Listeners Without Awt
How to Create a Generic Array in Java
Int Division: Why Is the Result of 1/3 == 0
How Do Servlets Work? Instantiation, Sessions, Shared Variables and Multithreading
Sort Arraylist of Custom Objects by Property
Why Does My Arraylist Contain N Copies of the Last Item Added to the List