寻找相当于Mechanize功能的请求

时间:2014-09-17 14:35:53

标签: python mechanize python-requests

我很想知道请求是否可以处理我在Mechanize中主要做的一些任务。

Mechanize可以轻松处理填写表单和提交表单,我很难在请求中尝试做同样的事情。

例如,

import mechanize
br = mechanize.Browser()
url = "https://www.euronext.com/en/data/download?ml=nyx_pd_stocks&cmd=default&formKey=nyx_pd_filter_values%3A18d1ee939a63d459d9a2a3b07b8837a7"
br.open(url)
br.select_form(nr=1)
br.form['format']=['2']
br.form['date_format']=['2']
response = br.submit().read()

请求是否等同于:

import requests
url = "https://www.euronext.com/en/data/download?ml=nyx_pd_stocks&cmd=default&formKey=nyx_pd_filter_values%3A18d1ee939a63d459d9a2a3b07b8837a7"
payload = {'format':'2','date_format':'2'}
r = requests.post(url, data=payload)

requests.post是否提交表格以下载页面上嵌入的CSV?

另外,有关其他信息,请参阅页面上的表单:

for form in br.forms():
    print form

<POST https://www.euronext.com/en/data/download?ml=nyx_pd_stocks&cmd=default&formKey=nyx_pd_filter_values%3A18d1ee939a63d459d9a2a3b07b8837a7  application/x-www-form-urlencoded
    <TextControl(search_block_form=)>
    <SubmitControl(op=Search) (readonly)>
    <RadioControl(search_type=[*quote, site])>
    <HiddenControl(form_build_id=form-af2eb21e9b6448ffca4e358d0b52f499) (readonly)>
    <HiddenControl(form_id=search_block_form) (readonly)>
    <HiddenControl(search_target=search_instruments) (readonly)>
    <HiddenControl(search_language=&lan=) (readonly)>>
<POST https://www.euronext.com/en/data/download?ml=nyx_pd_stocks&cmd=default&formKey=nyx_pd_filter_values%3A18d1ee939a63d459d9a2a3b07b8837a7 application/x-www-form-urlencoded
  <RadioControl(format=[*1, 2, 3])>
  <RadioControl(layout=[*2, 1])>
  <RadioControl(decimal_separator=[*1, 2])>
  <RadioControl(date_format=[*1, 2])>
  <SubmitControl(op=Go) (readonly)>
  <SubmitControl(op=Cancel) (readonly)>
  <HiddenControl(form_build_id=form-37e81285a4dbf60e091037f904bac2eb) (readonly)>
  <HiddenControl(form_id=nyx_download_form) (readonly)>>

2 个答案:

答案 0 :(得分:8)

requests没有填写与Mechanize相同的角色。

Mechanize加载实际的HTML表单并解析它,让您填写表单中各种元素的值。然后,当您要求Mechanize提交表单时,它将使用表单中的所有信息向服务器生成有效请求。这包括您未使用默认值(如果存在)提供新值的任何表单元素。这包括浏览器中不可见的任何隐藏表单元素。

使用robobrowser之类的项目;它包装requests以及BeautifulSoup来加载网页,解析表单元素,帮助您填写这些元素并再次提交。

如果您想使用 请求,您需要确保发布表单定义的所有字段。这意味着您需要查看method属性(默认为GET),action属性(默认为当前网址),以及所有input,{ {1}},selecttextarea个元素。服务器也可能需要HTTP请求中的其他信息,例如cookie或 Referer (sic)标头。

您打印的Mechanize信息表示它已从您未提供值的表单中解析了多个字段,例如。有问题的表单还包含一个名为button的隐藏输入字段,服务器可能依赖该字段。 Mechanize还会捕获与原始表单请求一起发送的任何cookie,并且服务器也可能需要这些cookie来接受请求。 robobrowser会考虑相同的背景。

答案 1 :(得分:0)

OP想要的是使用requestsBeautifulSoup这样做:

import requests
import urlparse
from bs4 import BeautifulSoup
url = "https://www.euronext.com/en/data/download?ml=nyx_pd_stocks&cmd=default&formKey=nyx_pd_filter_values%3A18d1ee939a63d459d9a2a3b07b8837a7"
resp = requests.get(url, allow_redirects=True)

soup = BeautifulSoup(resp.text, "lxml")
forms = soup.findAll("form")
params = dict([(parm.get("name"), parm.get("value")) for parm in forms[1].findAll("input")])
params.update({'format':'2','date_format':'2'})
formAction = forms[1].get("action")
# Make the relative URL absolute.
formAction = urlparse.urlunsplit(urlparse.urlsplit(url)[0:2] + urlparse.urlsplit(formAction)[2:])

resp = requests.post(formAction, data=params)