Python请求模块:发布并转到下一页

时间:2015-06-29 02:07:36

标签: python post mechanize twill

我正在使用python的请求模块在网页上填写表单。我提交表单作为POST请求,工作正常。我得到了POST的预期响应。但是,它是一个多步形式;在第一次"提交"该网站在同一页面上加载另一个表单(使用AJAX)。帖子回复有这个HTML页面。现在,如何使用此响应填写新页面上的表单?我可以用某种方式将Requests模块与Twill或Mechanize交织在一起吗?

这是POST的代码:

import requests
from requests.auth import HTTPProxyAuth
import formfill
from twill import get_browser
from twill.commands import *
import mechanize
from mechanize import ParseResponse, urlopen, urljoin

http_proxy  = "some_Proxy"
https_proxy  = "some_Proxy"

proxyDict = { 
              "http"  : http_proxy, 
              "https" : https_proxy
            }

auth = HTTPProxyAuth("user","pass")
r = requests.post("site_url",data={'key':'value'},proxies=proxyDict,auth=auth)

上面的回复r包含通过提交该表单而产生的新HTML页面。这个HTML页面还有一个我必须填写的表单。我可以通过某种方式将此r发送到斜纹或机械化,并使用Mechanize的表单填写API吗?任何想法都会有所帮助。

2 个答案:

答案 0 :(得分:3)

这里的问题是你需要实际与页面上的javascript进行交互。 requests虽然是一个优秀的图书馆,但它不支持javascript交互,它只是一个http库。

如果您想以有意义的方式与富含JavaScript的网页进行互动,我建议selenium。 Selenium实际上是一个完整的Web浏览器,可以像人一样完全导航。

主要问题是你会看到你的速度急剧下降。渲染网页比原始html请求需要更长的时间。如果这对您来说是一个真正的交易障碍,那么您有两个选择:

  • 无头:这里有很多选择,但我个人更喜欢casper。你可以通过无头看到大约3倍的浏览时间加速,但每个站点都不同。
  • 找到一种通过http执行所有操作的方法:大多数非可视站点功能具有等效的http功能。使用谷歌开发人员工具网络选项卡,您可以深入了解实际启动的请求,然后在python中复制这些请求。

就您提到的工具而言,mechanizetwill都不会有帮助。由于您的主要问题是javascript交互而不是cookie管理,并且这些框架都不支持javascript交互,因此您会遇到同样的问题。

更新:如果帖子回复实际上是新页面,那么您实际上根本没有与AJAX进行交互。如果是这样,并且您实际上拥有原始html,则应该简单地模仿表单将发送的典型http请求。您在第一个表单上使用的相同方法将适用于第二个表单。您可以从HTML响应中获取信息,也可以简单地对连续请求进行硬编码。

答案 1 :(得分:0)

使用Mechanize:

    private void CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
    {
        try
        {   
            // get current cell
            var cell = ((DataGridView)sender).Rows[e.RowIndex].Cells[e.ColumnIndex];
            // check new value. i need any number >= 5
            var c0 = 0;
            if (e.FormattedValue == null || !Int32.TryParse(e.FormattedValue.ToString(), out c0) || c0 < 5)
            {
                // bad value inserted

                // e.FormattedValue - is new value
                // cell.Value - contains 'old' value

                // choose any:
                cell.Value = cell.Value;    // this way we return 'old' value
                e.Cancel = true;            // this way we make user not leave the cell until he pastes the value we expect
            }
        }
        catch (Exception ex)
        {
        }
    }