0

我在 reddit 的 stackoverflow 上的某个地方找到了这段代码。我尝试为 hackthissite.org 修改它:

import urllib2
import urllib
import cookielib

# Store the cookies and create an opener to hold them
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

# Add our headers
opener.addheaders = [('User-agent', 'Tester')]

# Install the opener, changes the global opener to the one we just made
urllib2.install_opener(opener)

# URL for authentification
auth_url = 'https://www.hackthissite.org/user/login'

# Parameters to send
payload = {
    'username': 'myUser',
    'password': 'myPass',
    'btn_submit': 'Login'
}

# Encode payload
data = urllib.urlencode(payload)

# Build request object (supplying 'data' makes it a POST)
req = urllib2.Request(auth_url, data)

# Make request and store in resp
resp = urllib2.urlopen(req)

print resp

据我所知,我得到了正确的有效负载,这是 hackthissite.org 上的登录表单:

<form id="loginform" method="post" action="/user/login">
<div id="innerlogin">
        <script type="text/javascript">var userclicked=0; var passclicked=0;</script>
        <p><input type="text" name="username" class="login" value="" onclick="if(userclicked==0){this.value='';userclicked=1;};" title="Username" /></p>
        <p><input type="password" name="password" class="login" value="" onclick="if(passclicked==0){this.value='';passclicked=1;};" title="Password" /></p>
        <p><input type="submit" value="Login" name="btn_submit" class="submit-button" /></p>
</div>
</form>

我从服务器得到的响应是:

<addinfourl at 36515712 whose fp = <socket._fileobject object at 0x022D3DB0>>

如何登录网站?在这种情况下,服务器响应意味着什么?(添加信息网址?)

4

2 回答 2

6

我强烈建议您只看一下mechanize并使用它。它使这种事情几乎是微不足道的。例如,以下是您所提到的网站的接口方式:

from mechanize import Browser

br = Browser()
br.open("https://www.hackthissite.org/user/login")

br.select_form(predicate=lambda f: f.attrs.get('action') == '/user/login')
br["username"] = "myUser"
br["password"] = "myPass"
response = br.submit()

print response.read()

更新:解释这一行:

br.select_form(predicate=lambda f: f.attrs.get('action') == '/user/login')

select_form接受一个nr论点,或者一个name论点,或者一个predicate论点。如果您这样做br.select_form(nr=1),这将选择页面上的第二个表单。如果您这样做br.select_form(name="foobar"),这将选择页面上名为“foobar”的第一个表单。或者你可以给它一个函数,它接受一个HTMLForm对象,并返回是否应该是要选择的形式。

在上述情况下,我给它一个函数,如果"action"表单的属性是"/user/login". 如果您知道表单的名称或其在文档中的位置,那可能会更容易。

于 2013-07-29T23:46:41.873 回答
1
resp = urllib2.urlopen(req)

urlopen返回一个“类文件”对象,它本质上是一个句柄,您可以从中读取响应。如果您只是对服务器的响应文本感兴趣,您可以调用read响应对象:

print resp.read()

此外,您还有一些额外的方法info,例如为您提供有关响应标头的信息。

于 2013-07-30T00:20:06.163 回答