如何使用Python的Requests模块模拟HTTP post请求?

29

这个是我想要使用的模块,我想要自动填写一个表格。我想使用Requests而不是Mechanize,因为使用Mechanize需要先加载登录页面再填写和提交表单,而使用Requests则可以跳过加载阶段,直接进入POST消息阶段(希望如此)。基本上,我想尽可能减少登录过程中的带宽消耗。

我的第二个问题是,在登录过程和重定向之后,是否有可能仅检索页面标题而不完全下载整个页面?基本上,仅标题就足以告诉我登录是否成功,因此我想将带宽使用量最小化。

当涉及到HTTP请求等问题时,我有些新手,所以任何帮助都将不胜感激。顺便说一下,这是一个学校项目。

编辑:第一个问题已经得到了答复。现在我的问题是关于第二部分的。


1
你可以使用Chrome检查器来查看浏览器创建的post请求中传递了哪些值,然后从那里开始。 - bossylobster
2个回答

43

一些示例代码:

import requests

URL = 'https://www.yourlibrary.ca/account/index.cfm'
payload = {
    'barcode': 'your user name/login',
    'telephone_primary': 'your password',
    'persistent': '1'  # remember me
}

session = requests.session()
r = requests.post(URL, data=payload)
print r.cookies

第一步是查看您的源页面并识别正在提交的form元素(使用Firebug/Chrome/IE工具或者只查看源代码)。然后找到input元素,并确定所需的name属性(见上文)。

您提供的URL恰好有一个“记住我”的选项,尽管我没试过(因为我不能),但它暗示着会发出一个cookie在一段时间内避免进一步的登录 - 该cookie会保留在request.session中。

然后只需使用session.get(someurl, ...)来检索页面等等...


我尝试过了,但好像没有通过身份验证,虽然使用 Mechanize 可以。你知道可能出了什么问题吗? 编辑 对不起,实际上它已经可以了。我只是打错了一个字 :) - Display Name
你真是救星啊!我以为我得整天忍受 ColdFusion 的烦恼。结果只花了 15 分钟就完成了 8 小时的手动下载! - Blairg23
那么我该如何发送文件呢? - Yash Kumar Verma
r = session.post(URL, data=payload)``` you declared `session` - LeonF

17

要在requests的get或post函数中使用身份验证,只需提供auth参数。像这样:

response = requests.get(url, auth=('username', 'password'))请参阅Requests 身份验证文档获取更详细的信息。

使用Chrome开发者工具,您可以检查包含要填写和提交的表单的HTML页面的元素。有关如何执行此操作的说明,请转到此处。您可以找到需要填充您的POST请求数据参数的数据。如果您不担心验证正在访问的站点的安全证书,则还可以在GET参数列表中指定。

如果您的HTML页面具有这些元素用于网络表单发布:

<textarea id="text" class="wikitext" name="text" cols="80" rows="20">
This is where your edited text will go
</textarea>
<input type="submit" id="save" name="save" value="Submit changes">

那么向此表单提交的Python代码如下:

import requests
from bs4 import BeautifulSoup

url = "http://www.someurl.com"

username = "your_username"
password = "your_password"

response = requests.get(url, auth=(username, password), verify=False)

# Getting the text of the page from the response data       
page = BeautifulSoup(response.text)

# Finding the text contained in a specific element, for instance, the 
# textarea element that contains the area where you would write a forum post
txt = page.find('textarea', id="text").string

# Finding the value of a specific attribute with name = "version" and 
# extracting the contents of the value attribute
tag = page.find('input', attrs = {'name':'version'})
ver = tag['value']

# Changing the text to whatever you want
txt = "Your text here, this will be what is written to the textarea for the post"

# construct the POST request
form_data = {
    'save' : 'Submit changes'
    'text' : txt
} 

post = requests.post(url,auth=(username, password),data=form_data,verify=False)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接