通过Python获取表单数据

时间:2011-09-17 17:02:58

标签: python cgi urllib

我希望获取需要传递到特定网站并提交的表单数据。下面是我需要模拟的html(仅限表单)。我已经在这个工作了几个小时,但似乎无法得到任何工作。我希望这可以在Google App Engine中使用。任何帮助都会很好。

<form method="post" action="/member/index.bv"> 
        <table cellspacing="0" cellpadding="0" border="0" width="100%"> 
            <tr> 
                <td align="left"> 
                    <h3>member login</h3><input type="hidden" name="submit" value="login" /><br /> 
                </td> 
            </tr> 
            <tr> 
                <td align="left" style="color: #8b6c46;"> 
                    email:<br /> 
                    <input type="text" name="email" style="width: 140px;" /> 
                </td> 
            </tr> 
            <tr> 
                <td align="left" style="color: #8b6c46;"> 
                    password:<br /> 
                    <input type="password" name="password" style="width: 140px;" /> 
                </td> 
            </t>
            <tr> 
                <td> 
                    <input type="image" class="formElementImageButton" src="/resources/default/images/btnLogin.gif" style="width: 46px; height: 17px;" /> 
                </td> 
            </tr> 
            <tr> 
                <td align="left"> 
                    <div style="line-height: 1.5em;"> 
                        <a href="/join/" style="color: #8b6c46; font-weight: bold; text-decoration: underline; ">join</a><br /> 
                        <a href="/member/forgot/" style="color: #8b6c46; font-weight: bold; text-decoration: underline;">forgot password?</a><input type="hidden" name="lastplace" value="%2F"><br /> 
                        having trouble logging on, <a href="/cookieProblems.bv">click here</a> for help
                    </div> 
                </td> 
            </tr> 
        </table> 
    </form>

目前我正在尝试使用此代码来访问它,但它无法正常工作。我对此很陌生,所以也许我只是错过了它。

import urllib2, urllib

url = 'http://blah.com/member/index.bv'
values = {'email' : 'someemail@gmail.com',
          'password' : 'somepassword'}

data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()

2 个答案:

答案 0 :(得分:2)

这是第三方网站的登录页面吗?如果是这样,可能还有更多内容,而不仅仅是发布表单输入。

例如,我只是在我自己的一个网站上使用登录页面尝试了这个。一个简单的帖子请求在我的情况下不起作用,这也可能与您正在访问的登录页面相同。

对于初学者,登录表单可能具有隐藏的csrf token值,您必须在发布登录请求时发送该值。这意味着您必须首先get登录页面并解析生成的csrf token值的html。服务器也可能在登录请求中需要其会话cookie。

我正在使用requests模块来处理get / post和beautifulsoup来解析数据。

import requests                                                                                                                                                                                             
import zlib                                                                                                                                                                                                 
from BeautifulSoup import BeautifulSoup                                                                                                                                                                     

# first get the login page                                                                                                                                                                                                    
response = requests.get('https://www.site.com')                                                                                                                                                   
# if content is zipped, then you'll need to unzip it                                                                                                                                                                                 
html = zlib.decompress(response.read(), 16+zlib.MAX_WBITS)  
# parse the html for the csrf token                                                                                                                                                
soup = BeautifulSoup(html)                                                                                                                                                                                  
csrf_token = soup.find(name='input', id='csrf_token')['value']                                                                                                                                              

# now, submit the login data, including csrf token and the original cookie data                                                                                                                                          
response = requests.post('https://www.site.com/login',                                                                                                                                       
            {'csrf_token': csrf_token,                                                                                                                                                                  
             'username': 'username',                                                                                                                                                                            
             'password': 'ckrit'},                                                                                                                                                                           
             cookies=response.cookies)                                                                                                                                                                   

login_result = zlib.decompress(response.read(), 16+zlib.MAX_WBITS)                                                                                                                                                  
print login_result    

我不能说GAE是否会允许这样做,但至少它可能有助于弄清楚在您的特定情况下您可能需要什么。此外,正如卡尔指出的那样,如果使用提交输入来触发帖子,则必须将其包括在内。在我的特定示例中,这不是必需的。

答案 1 :(得分:1)

您缺少隐藏的submit = login参数。你试过了吗?

import urllib2, urllib

url = 'http://blah.com/member/index.bv'
values = {'submit':'login',
          'email' : 'someemail@gmail.com',
          'password' : 'somepassword'}

data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()