【问题标题】:python, authentication not recognised - urllib2, requests, asp.netpython,无法识别身份验证 - urllib2,请求,asp.net
【发布时间】:2016-03-22 12:31:26
【问题描述】:

虽然我在这方面不是特别先进,但我过去在使用 urrlib2、requests 和 scrapy 方面取得了一些成功,但这让我很困惑。因此,经过大量搜索并将我的头撞在键盘上,我会继续问。

我想获取一个网站的 html 源代码,但是在使用我的用户名和密码后,我不断收到一个页面,上面说我的用户名和密码错误。它们在浏览器中运行良好,并且一旦登录,源代码就很容易获得(通过浏览器)。但我似乎无法通过 python/终端获得相同的结果。我将在下面列出我的一些尝试(来自这些有用的页面):

使用 urllib2:

req = Request(website, headers={ 'User-Agent': 'Mozilla/5.0' })
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string)
readweb = urlopen(req).read()

另一个版本:

passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None, theurl, username, password)

authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)

pagehandle = opener.open(theurl)
return pagehandle.read()

并尝试使用请求:

r = requests.session()
try:
    r.post(theurl, data={'username' : 'username', 'password' : 'password', 'remember':'1'})
except:
    print('Sorry, Unable to...')
result = r.get(theurl)
return result.text

我也尝试过使用scrapy,但无论我使用哪个库,它都会返回显示我的密码/详细信息错误的页面的html。我猜这与我发送的标题/授权(?)有关,但我不太确定。非常感谢任何帮助,请让我知道我可以更新哪些其他细节(我已经为此熬了半夜,所以如果这篇文章没有意义,请原谅我!)

编辑:

以下是对 Prashant 回答的回溯响应(减去密码等):

Traceback (most recent call last):

文件“/Users/Hatsaw/newpy/pras.py”,第 3 行,在 r = requests.get(URL, auth=('username','password')) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests-2.9.0-py2.7.egg/requests/api.py”,第 67 行,在获取 返回请求('get', url, params=params, **kwargs) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests-2.9.0-py2.7.egg/requests/api.py”,第 53 行,在请求中 返回 session.request(method=method, url=url, **kwargs) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests-2.9.0-py2.7.egg/requests/sessions.py”,第 468 行,在请求中 resp = self.send(prep, **send_kwargs) 文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests-2.9.0-py2.7.egg/requests/sessions.py”,第 576 行,发送 r = adapter.send(request, **kwargs) 发送中的文件“/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests-2.9.0-py2.7.egg/requests/adapters.py”,第 437 行 引发 ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='website', port=80): Max retries exceeded with url: /dashboard/ (由 NewConnectionError(': 无法建立新连接: [Errno 8] nodename or servname provided , 或未知',))

编辑:

好的,我现在正在使用 mechanize(下面推荐),这就是我要返回的内容(不确定这是我的根本问题的另一个实例还是我无法使用 mechanize!):

Traceback (most recent call last):

文件“/Users/Hatsaw/newpy/pras2.py”,第 13 行,在 browser.form['email'] = '电子邮件地址' setitem 中的文件“build/bdist.macosx-10.6-intel/egg/mechanize/_form.py”,第 2780 行 文件“build/bdist.macosx-10.6-intel/egg/mechanize/_form.py”,第 3101 行,在 find_control _find_control 中的文件“build/bdist.macosx-10.6-intel/egg/mechanize/_form.py”,第 3185 行 mechanize._form.ControlNotFoundError:没有控件匹配名称“电子邮件”

编辑:

仍在为此苦苦挣扎,所以在这个项目的时间用完之前,这是最后的努力,我必须手动进入并获取所有 html!手指交叉..

好的,所以根据 barny 的建议,我重新开始使用请求,并且我正在尝试为帖子提供 cookie 信息,这些信息是我从成功的浏览器登录中获得的。我不确定我这样做是否正确,但我正在使用:

cookies = {'PHPSESSID':'5udcifi6p43ma3h1fnpfqghiu0'}
result = sess.get(the_url, cookies=cookies)

现在,我收到了内部服务器错误响应。经过一番研究,aspnet 表单似乎是问题所在:

我只是想先检查一下我没有对请求做错什么,然后也许我会按照上面 SO 链接中 Martijn Pieters 的推荐探索 BeautifulSoup/robobrowser。

这是 html 的表单部分的要求:

<form name="aspnetForm" method="post" action="" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
<input type="hidden" name="__VIEWSTATEFIELDCOUNT" id="__VIEWSTATEFIELDCOUNT" value="2" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTkwNzg1NTQ3OA9kFgJmD2QWAmYPZBYGAgetc." />
<input type="hidden" name="__VIEWSTATE1" id="__VIEWSTATE1"     value="ZyBBIEhvbWUVIE5lZ290aWF0ZSBBZ3JlZW1lbnRzEiBSZetc." />
</div>

<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
    theForm.__EVENTTARGET.value = eventTarget;
    theForm.__EVENTARGUMENT.value = eventArgument;
    theForm.submit();
}
}
//]]>
</script>


<script src="/WebResource.axd?d=t2SAOwDGkbrEfkmUaMOR9sPLXqgxfeenNayRja3DNK2R8JEcH-StTTuiaqXpzp--PAISn3vzVbWQ7biREwPkibCmbAE1&amp;t=635586505120000000" type="text/javascript"></script>


<script src="/ScriptResource.axd?d=EL6tXtJfNfGSoQwhYtVnYEqw4oKvuwBBI4etc."     type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
if (typeof(Sys) === 'undefined') throw new Error('ASP.NET Ajax client-side framework failed to load.');
//]]>
</script>

<script src="/ScriptResource.axd?d=qCmNMcECQa0tfmMcZdwJeeOdcyetc." type="text/javascript"></script>
<div>

<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="FC5C7135" />
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEdABB2xJRvPLCcg6GsBqRFCtw6Xg91QEu10etc." />
</div>

所以。一些小问题。

  • 我的“用户/密码”术语是否必须与源代码匹配,即用户名 = 用户名或用户?: 我现在丢失了在 html 中找到它的位置,但我找到了 'ctl00$cphMain$tbUsername' 和 'ctl00$cphMain$tbPassword'...

  • 我是否需要将密码和/或用户名作为 base64.encodestring 发送? (不知道是不是这个问题,但是密码中含有!@$等字符)

  • 我需要添加从浏览器中找到的所有 cookie 字段还是只添加 PHPSESSID?以下是我在 cookie 中的字段:

ASP.NET_SessionId、CFID、CFTOKEN、__atuvc、__utma、__utmb、__utmc、__utmt、__utmz、BRO_CALLME、BRO_ID、BRO_LOGIN、BRO_MEMBER、BROAUTH、ISFULLMEMBER、phpMBLink、__CT_Data、WRUID

  • 有网站 (www.website.com)、登录页面 (www.website.com/login),然后是内容 (www.website.com/content)。我认为我使用(成功登录)登录页面中的 cookie 并将其“发送”到内容页面是否正确?我应该手动执行此操作(从浏览器 cookie 信息中输入字段详细信息)还是在代码中(因此,在下面的代码中我将使用:cookies = r_login.cookies)?

最后,这是我当前使用的返回内部服务器错误的代码..:

import requests

the_url = 'the_url'
login = the_url + '/login'
content = the_url + '/content'
username = 'username'
password = 'password'

sess = requests.Session()
sess.auth = ('username', 'password')
sess.get(the_url)

payload = {'ctl00$cphMain$tbUsername': username, 'ctl00$cphMain$tbPassword': password}
r_login = sess.post(login, data=payload)

cookies = {'PHPSESSID':'5udcifi6p43ma3h1fnpfqghiu0', 'ASP.NET_SessionId':'aspnet', 'BRO_LOGIN':'bro_login'}
r_data = s.get(content, cookies=cookies, data=payload)

print r_data.text

抱歉,这已经相当长了,如果我需要将它分成几个帖子,请告诉我 - 我一开始以为是一个简单的问题已经变成了其他问题!

【问题讨论】:

    标签: python asp.net passwords python-requests robobrowser


    【解决方案1】:
    import requests
    URL = "http://www.facebook.com'
    r = requests.get(URL, auth=('username','password'))
    source = r.text
    print source
    

    -----改变-----

    import mechanize
    browser = mechanize.Browser()
    browser.set_handle_robots(False)
    cookies = mechanize.CookieJar()
    browser.set_cookiejar(cookies)
    browser.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.41 Safari/534.7')]
    browser.set_handle_refresh(False)
    
    url = 'http://www.facebook.com/login.php'
    self.browser.open(url)
    self.browser.select_form(nr = 0)       #This is login-password form -> nr = number = 0
    self.browser.form['email'] = YourLogin
    self.browser.form['pass'] = YourPassw
    response = self.browser.submit()
    print response.read()
    

    Link

    【讨论】:

    • 酷,我没有听说过mechanize,我现在已经下载了它并尝试了一下(我假设你的代码的后半部分需要进入一个函数?或类? )它还没有打印任何响应,但我会在一段时间内猛烈抨击它,看看我能做什么,干杯 Prashant,我会尽快更新
    • 好的,所以我认为我的 mechanize 运行正常,但我遇到了一个错误(见上文) - 这与您提到的表格编号有关吗?我把它留在了 0 点。
    • 登录网站,查看您的 cookie 并复制 PHPSESSID 的值。然后将其粘贴到: cookie = 在 config.ini 中并设置 keepsignedin = 1
    • 嗨,Prashant,感谢您在这方面的帮助,我现在有了 PHPSESSID,但我有点困惑将它粘贴到哪里等等 - 'config.ini' 是机械化的东西吗?还是网络浏览器的东西?我已经搜索过,但仍然不确定..
    • 如果您使用请求会话,它将保存 cookie 并在后续请求中自动提供。
    【解决方案2】:

    胜利!

    好的,感谢 Prashant 和 barny 的回复,非常感谢 Martijn Pieters 通过这篇文章: Sending an ASP.net POST with Python's Requests

    我发现我的救赎是 robobot

    代码如下:

    from robobrowser import RoboBrowser
    
    the_url = 'the_url'
    login = the_url + '/login'
    content = the_url + '/content'
    username = 'username'
    password = 'password'
    
    browser = RoboBrowser(parser='lxml')
    
    browser.open(login)
    form = browser.get_forms()  
    
    # You can use '.get_form()' for a specific form but I'm finding it easier to 
    # using '.get_forms()' to get all the forms and then I'm just interested 
    # in the first one:
    
    form = form[0]
    print form     # this will give you the information you need to 
                   # now enter your password details:   
    
    form['the_user'].value = username
    form['the_pass'].value = password
    
    browser.submit_form(form)
    
    # and then because I'm after the html of certain content pages:
    
    browser.open(content)
    source = str(browser.parsed)
    return source
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 2015-03-21
      • 1970-01-01
      • 2014-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多