【问题标题】:Looking for Requests equivalent of Mechanize capabilities寻找等效于机械化功能的请求
【发布时间】:2014-11-11 15:55:45
【问题描述】:

我有兴趣看看 Requests 是否可以处理我主要在 Mechanize 中完成的一些任务。

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

例如,

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)>>

【问题讨论】:

    标签: python mechanize python-requests


    【解决方案1】:

    requests 与 Mechanize 的角色不同。

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

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

    如果您想使用 just 请求,您需要确保发布表单定义的所有字段。这意味着您需要查看method 属性(默认为GET)、action 属性(默认为当前URL)以及input、select、textarea 和@ 987654331@ 元素。服务器还可能期望 HTTP 请求中包含其他信息,例如 cookie 或 Referer (sic) 标头。

    例如,您打印的 Mechanize 信息表明,它已从表单中解析出更多字段,而您没有为其提供值。有问题的表单还包含一个名为 form_build_id 的隐藏输入字段,例如,服务器可能依赖该字段。 Mechanize 还会捕获随原始表单请求发送的任何 cookie,并且服务器也可能需要这些 cookie 才能接受请求。 robobrowser 会考虑相同的上下文。

    【讨论】:

    • 你会选择 robobrowser 而不是 Mechanize 还是 Selenium?
    • @chishaku:是的。 BeautifulSoup 和 requests 是比 Mechanize 提供的更好的 API,而且 Selenium 太重了,除非你绝对需要支持 JavaScript。
    【解决方案2】:

    OP 想要的可以使用requests 和BeautifulSoup 来完成,如下所示:

    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)
    

    【讨论】:

      猜你喜欢
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多