Forum Archive

iPhone auto login code

space dane

Hello,

Can anyone tell me how write a code to auto fill a login and password without selenium or mechaniz. This is to be ru in pythonista on an iPhone. Thanks

low

Are you trying to fill passwords on mobile apps, or on websites?

mikael

@space-dane, use the Pythonista WebView. It has full support for Javascript, frames etc.

Since Javascript is a pain to write and test, I wrote a JSWrapper that lets you manipulate js in Python. You can find it here.

With it, you can fill in the fields by name like this:

js = JSWrapper(webview)
js.set_field('username', 'your username')
js.set_field('passwd', 'your password')

And submit the first form on the page:

js.submit()

... or, if there are multiple forms, by name or id of the form element:

js.by_name('form1').submit()

When you get to a content page, you can pick out items by id, by name, or with XPath. A simple example of the last option:

js.xpath('head/title').value()

Or you can collect a list of repeating elements, e.g. name attributes of all input elements:

js.list_each('input/@name')

More complicated alternative collects a dictionary of several elements, e.g. different cells from the rows of a table:

cell_values = js.for_each('table//tr').map(
  key='td[1]',
  some_value='td[3]'
)
for key in cell_values:
  print(key, cell_values[key]['some_value'])

WebView is asynchronous, and the actual scraping on a page can start when the webview's webview_did_finish_load callback fires. As this is fired for every page, we need a kind of a state machine to keep track where we are in the flow of pages. To help with this, the file includes a ready-made delegate where you map urls to handler functions and manage the flow by always setting the next expected handler. Below is a "full" example for a hypothetical login & content scrape. Note the example on retrieving whole body HTML content, useful when developing the scraper, and that the present` on the last line is optional, depending on whether you want to watch things happening live or not.

import jswrapper

class DemoScraper(jswrapper.WebScraper):

  def __init__(self, webview):
    super().__init__(webview)
    self.url_map = {
      self.login_page: 'starting_url',
      self.content_page: 'pther_url'
    }
    self.handler = self.login_page

  def login_page(self):
    self.set_field('username', 'your username')
    self.set_field('passwd', 'your password')

    self.handler = self.content_page
    self.by_name('form1').submit()

  def content_page(self):
    print(self.xpath('body').html())
    print(self.xpath('head/title').value())

wv = ui.WebView()
ds = DemoScraper(wv)
wv.load_url('starting_url')
wv.present()
augusto

@mikael, I’m testing jsui but I have a problem with AttributeWrapper, it is not defined. Are you still developing it? or from where I can download the code. Thanks, very good job.

mikael

@augusto, I am just starting with it, and do not yet consider it fit for any kind of use. I am currently refactoring the initial exploratory version and moving it to a separate repository with a more sensible file structure.

That said, as an immediate fix, you can replace any mention of AttributeWrapper with JSWrapper, and I will let you know as soon as the new version is in some workable shape.

JonB

@mikael
For what its worth, you might want to look at
https://forum.omz-software.com/topic/1804/debugging-in-javascript-in-pythonista

Your JSWrapper is a lot nicer than what I had, but what you might find useful was the on_error logging -- basically having javascript errors automatically get logged back to the console (via a custom uri scheme that the webview is watching for). the silent nature of javascript errors on ios made developing a pain.

mikael

@JonB, thanks, I did remember your code from back when, and it is included in the latest version. It is simply a godsend.

mikael

@JonB, still, can be difficult to tell where the error really comes from, when you have these bits and pieces of eval_js flying around.