How to login into the Fidelity website and navigate within it?

旧时模样 提交于 2020-06-29 08:31:41

问题


I would love to get some help in logging into the Fidelity website and navigate within it. My attempts so far have not led me to anywhere significant. So here is the code that I have written, after much consultation with answers around the web. The steps are:

  1. Login to Fidelity
  2. Check if response code not 200, but is 302 or 303 and my code passes this test (with a code of 302).
  3. Then I check the number of cookies returned (there were 5) and for each cookie I try to navigate to a different web page within Fidelity (I do this five times, once for each cookie, simply because I do not know which subscript "j" of the variable "cookie" will work).

function loginToFidelity(){
  var url = "https://www.fidelity.com"; 
  var payload = {
    "username":"*********", 
    "password":"*********" 
  }; 
  var opt = {
    "payload":payload,"method":"post","followRedirects" : false
  };
  var response = UrlFetchApp.fetch(encodeURI(url),opt);
  if ( response.getResponseCode() == 200 ) { 
    Logger.log("Couldn't login.");
    return
  } 
  else if (response.getResponseCode() == 303 || response.getResponseCode() == 302) {
    Logger.log("Logged in successfully. " + response.getResponseCode());
    var cookie = response.getAllHeaders()['Set-Cookie']
    for (j = 0; j < cookie.length; j++) {
      var downloadPage = UrlFetchApp.fetch("https://oltx.fidelity.com/ftgw/fbc/oftop/portfolio#activity", 
          {"Cookie" : cookie[j],"method" : "post","followRedirects" : false,"payload":payload});
      Logger.log(downloadPage.getResponseCode())
      Logger.log(downloadPage.getContentText())
    }
  }
}

For each choice of the subscript "j", I get the same answer for the ResponseCode (always 302) as well as the same answer for ContentText. The answer for ContentText is obviously incorrect as it is not what it is supposed to be. The ContentText is shown below:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://login.fidelity.com/ftgw/Fidelity/RtlCust/Login/Init?AuthRedUrl=https://oltx.fidelity.com/ftgw/fbc/oftop/portfolio">here</a>.</p>
</body></html>

Based on this, I have two questions:

  1. Have I logged into the Fidelity site correctly? If not, why do I get a response code of 302 in the login process? What do I need to do differently to login correctly?

  2. Why am I getting such a strange and obviously incorrect answer for my ContentText while getting a perfectly reasonable ResponseCode of 302? What do I need to do differently, so that I can get the password-controlled page within Fidelity, whose url is "https://oltx.fidelity.com/ftgw/fbc/oftop/portfolio#activity"?

NOTE: Some other tests have been done in addition to the one stated above. Results from these tests are provided in the discussion below.


回答1:


Here is something which worked for me. You may have found the solution already, not sure. Remember to fill in your loginid where the XXXX is and the pin number for YYYY.

I understand this is python code, not the google script, but you get the idea about the code flow.

import requests, sys, lxml.html
s = requests.Session()
r = s.get('https://login.fidelity.com')
payload = {

'DEVICE_PRINT' : 'version%3D3.5.2_2%26pm_fpua%3Dmozilla%2F5.0+(x11%3B+linux+x86_64%3B+rv%3A41.0)+gecko%2F20100101+firefox%2F41.0%7C5.0+(X11)%7CLinux+x86_64',
    'SavedIdInd' : 'N',
    'SSN' : 'XXXXX',
    'PIN' : 'YYYYY'
}

r = s.post(login_url, data=payload, headers=dict(referer='https://login.fidelity.com'))
response = s.get('https://oltx.fidelity.com/ftgw/fbc/oftop/portfolio')

print response.content



回答2:


mwahal, you left out the critical form action url (your login_url is undefined)

this works (if added to your python code)

login_url = 'https://login.fidelity.com/ftgw/Fas/Fidelity/RtlCust/Login/Response/dj.chf.ra'

btw here's the result of the print after the post showing successful login

{"status": 
    {
        "result": "success", 
        "nextStep": "Finish", 
        "context":  "RtlCust"
    }   
} 

or adding some code:

if r.status_code == requests.codes.ok:
    status = r.json().get('status')
    print(status["result"])

gets you "success"




回答3:


Unfortunately the answer from @mwahal doesn't work anymore - I've been trying to figure out why, will update if I do. One issue is that the login page now requires a cookie from the cfa.fidelity.com domain, which only gets set when one of the linked JavaScript files is loaded.

One alternative is to use selenium, if you just want to navigate the site, or seleniumrequests if you want to tap into Fidelity's internal APIs.

There is a hitch with seleniumreqeusts for the transactions API... the API requires Content-Type: application/json and seleniumrequests doesn't seem to support custom headers in requests. So I use selenium to log in, call one of the APIs that doesn't need that header, copy then edit the response's request header, and use regular requests to get the transactions:

from seleniumrequests import Chrome
import requests

# Log into Fidelity
driver = Chrome()
driver.get("https://www.fidelity.com")
driver.find_element_by_id("userId-input").send_keys(username)
driver.find_element_by_name("PIN").send_keys(password)
driver.find_element_by_id("fs-login-button").click()

r = driver.request('GET', 'https://digital.fidelity.com/ftgw/digital/rsc/api/profile-data')
headers = r.request.headers
headers['accept'] = "application/json, text/plain, */*"
headers['content-type'] = "application/json"

payload = '{"acctDetails":[{"acctNum":"<AcctId>"}],"searchCriteriaDetail":{"txnFromDate":1583639342,"txnToDate":1591411742}}'
api = "https://digital.fidelity.com/ftgw/digital/dc-history/api"
r = requests.post(api, headers=headers, data=payload)

transactions = r.json()


来源:https://stackoverflow.com/questions/52194600/how-to-login-into-the-fidelity-website-and-navigate-within-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!