我正在编写一个Python 2.7脚本,使用Requests自动访问特定网站。出于“安全原因”,网站要求提供与请求URL 匹配的Referer标头。该URL由params
dict中的许多项构成,传递给requests.post()。
在发出请求之前,有没有办法确定请求将使用的URL是什么,以便可以将Referer标头设置为此正确值?我们假设我有很多参数:
params = { 'param1' : value1, 'param2' : value2, # ... etc
}
base_url = "http://example.com"
headers = { 'Referer' : url } # but what is 'url' to be?
requests.post(base_url, params=params, headers=headers) # fails as Referer does not match final url
我想一个解决方法是在事后发出请求并查看URL是什么。但是这有两个问题 - 1.它会给脚本的执行时间增加很多开销,因为会有很多这样的请求,而且它实际上并不是一个有用的解决方法,因为服务器实际上将请求重定向到另一个URL,因此之后阅读它不会给出正确的Referer值。
我想请注意,我有这个脚本使用urllib / urllib2,我试图用Requests写它,看它是否可能,也许更简单。这不是一个脚本必须遵循的复杂过程,但它可能略微超出了请求的范围。那很好,我只想确认是这种情况。
答案 0 :(得分:2)
我想我找到了一个基于Prepared Requests的解决方案。概念是Session.prepare_request()
将执行所有操作以准备请求,除非发送它,这允许我的脚本然后读取准备好的请求的url,其现在包括其顺序由dict顺序确定的参数。然后它可以适当地设置Referer头,然后发出原始请求。
params = {'param1' : value1, 'param2' : value2, # ... etc
}
url = "http://example.com"
# Referer must be correct
# To determine correct Referer url, prepare a request without actually sending it
req = requests.Request('POST', url, params=params)
prepped = session.prepare_request(req)
#r = session.send(prepped) # don't actually send it
# add the Referer header by examining the prepared url
headers = { 'Referer': prepped.url }
# now send normally
r = session.post(url, params=params, data=data, headers=headers)
答案 1 :(得分:0)
您似乎已在“请求”中正确找到了prepare_request功能。
但是,如果你仍想使用初始方法,我相信你可以使用你的base_url作为你的Referer:
base_url = "http://example.com"
headers = { 'Referer' : base_url }
requests.post(base_url, params=params, headers=headers)
我怀疑这是因为您的POST将PARAMS直接附加到base_url。例如,如果你在:
http://www.example.com/trying-to-send-upload/
在此POST中添加一些参数,然后使用:
referer = "http://www.example.com/trying-to-send-something/"
headers = { 'Referer' : referer, 'Host' : 'example.com' }
requests.post(referer, params=params, headers=headers)
<强> ADDED 强>
在您创建了URL字符串后,我会使用简单的语句直观地检查我的网址:
print(post_url)
如果这样做很好,您应该打印出您要发布到的服务器的回复详情,因为它也可能会为您提供一些关于您的查询被拒绝的提示:
s = requests.post(referer, params=params, headers=headers)
print(s.status_code)
print(s.text)
很高兴听到这对您有效。