Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ And it is possible to use it as a tool to quickly debug a login form::
- password: secret


You can also provide a selector to the method as an XPath so select a particular form on the page.
This can be useful if you have more than one form present, and the score mechanism selects the incorrect form::

>>> from loginform import fill_login_form
>>> import requests
>>> url = "https://twitter.com"
>>> r = requests.get(url)
>>> fill_login_form(url, r.text, "john", "secret", selector='//form[@class="signin"]')
>>> fill_login_form(url, r.text, "john", "secret", selector='//form[@class="signup"]')


Testing
-------

Expand Down
9 changes: 7 additions & 2 deletions loginform.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ def _form_score(form):

def _pick_form(forms):
"""Return the form most likely to be a login form"""
for form in forms:
print(form)
return sorted(forms, key=_form_score, reverse=True)[0]


Expand Down Expand Up @@ -72,9 +74,12 @@ def submit_value(form):
return []


def fill_login_form(url, body, username, password):
def fill_login_form(url, body, username, password, *args, **kwargs):

selector = kwargs.get('selector', '//form')
Copy link
Member

@dangra dangra May 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for **kwargs, extend function signature to:

def fill_login_form(url, body, username, password, selector='//form'):


doc = html.document_fromstring(body, base_url=url)
form = _pick_form(doc.xpath('//form'))
form = _pick_form(doc.xpath(selector))
userfield, passfield = _pick_fields(form)
form.fields[userfield] = username
form.fields[passfield] = password
Expand Down
7 changes: 6 additions & 1 deletion test_samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,13 @@ def main():
if opts.list:
print("\n".join(list_samples()))
else:
print(args)
url = args[0]
r = requests.get(url)
headers = {
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks useful but do you mind submitting this change in a different PR. I think it needs some extra thoughts like setting it from an command line flag that defaults to "Mozilla/4.0..."

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dangra Any thoughts on merging this PR, I am using this library in one of my projects, it will be very helpful for me if this feature is part of it.

}

r = requests.get(url, headers=headers)
values = fill_login_form(url, r.text, "USER", "PASS")
values = (url, values)
print(json.dumps(values, indent=3))
Expand Down