【发布时间】: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&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