【问题标题】:Requests interacting strangely with redirect请求与重定向奇怪地交互
【发布时间】:2014-04-25 21:10:58
【问题描述】:

尝试编写一个小爬虫来提取 marathonguide.com 上列出的马拉松比赛的完赛结果,但无法重定向以显示正确的页面。

网站上的导航很简单:

当我遵循标准表单提交导航时,此结果页面仅显示整理器数据。但是,如果我刷新此页面,或直接输入 URL,则 URL 将反映结果页面,但会显示 事件页面

这是我的代码:

import requests
from bs4 import BeautifulSoup

marathon = 'http://www.marathonguide.com/results/browse.cfm?MIDD=472131103'

s = requests.session()
p = s.get(marathon)

race_range = 'B,201,300,50062'
rp = 'http://www.marathonguide.com/results/makelinks.cfm'
data = {'RaceRange':race_range, 'RaceRange_Required':'You must make a selection before viewing results.', 'MIDD':'472131103', 'SubmitButton':'View'}

results = s.post(rp, data=data)

print results.status_code
print results.url    
print results.text

>>> 200
>>> http://www.marathonguide.com/results/browse.cfm?MIDD=472131103&Gen=B&Begin=201&End=300&Max=50062
>>> HTML from http://www.marathonguide.com/results/browse.cfm?MIDD=472131103

根据我得到的 HTML,我被发送回事件页面,想知道为什么服务器不喜欢我的 POST。辩论使用 selenium 来模拟用户体验,但我确信我的请求代码中缺少一些小东西。

编辑:根据反馈我更新了问题以反映我的实际代码。

【问题讨论】:

  • 在 SO 中允许共享 URL。但是,请注意,如果这是您正在编写的专有代码(例如,对于您的公司),或者该站点是私有网络(您将其开放给外部访问)。否则,它是相当安全的。大量的 URL 一直在共享。也就是说,我想你最好分享它,以便我们检查它。 :)
  • 感谢@Nanashi,相应地更新了我的问题。
  • 抱歉回复晚了,一会儿再发一个答案。 :)

标签: python web-scraping beautifulsoup python-requests


【解决方案1】:

您被引导回活动页面的原因是这个特定的 POST 请求需要推荐。这意味着如果直接访问它,而不是来自预期的 URL,它将不会处理您的请求。这可能会阻碍简单的表单数据 POST 操作以及字符串操作。

一个简单的测试,看看它是否在页面中:尝试立即转到结果页面。怎么了?几乎什么都没有,因为您会被引导回带有相应 MIDD 的事件页面。即使你尝试操作字符串,它也不起作用。

解决此问题的方法是找到引用的 URL。您可以通过检查标题并查找Referer 键来执行此操作。请看下面的截图。

然后我们得到这个值并合并到我们的 POST 请求中。以下是您的代码,经过修改以适应上述操作。

import requests
from bs4 import BeautifulSoup

marathon = 'http://www.marathonguide.com/results/browse.cfm?MIDD=472131103'

s = requests.session()
p = s.get(marathon)

race_range = 'M,201,300,50062'
rp = 'http://www.marathonguide.com/results/makelinks.cfm'
data = {'RaceRange':race_range, 'RaceRange_Required':'You must make a selection before viewing results.', 'MIDD':'472131103', 'SubmitButton':'View'}
headers = {
"Referer":"http://www.marathonguide.com/results/browse.cfm?MIDD=472131103",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36"
}

results = s.post(rp, data=data, headers=headers)
soup = BeautifulSoup(results.content)

rows = soup.find_all("tr", {"bgcolor":"#CCCCCC"})
for row in rows:
  print row.find("td").get_text()

注意headers 行以及新的results = s.post... 行。另外,请注意正确的性别值不是B,而是M。检查race_range 行以了解我的意思。

最后结果如下:

JAKOB SKOTT (M37)
MATIAS MARQUEZ (M44)
JOSE ESPINOSA (M33)
MATTHEW BERGENHOLTZ (M32)
MICHAEL KNAK (M33)
NICK BEDBURY (M25)
BOB LARUE (M29)
JONATAN TROLDBORG (M19)
PEDER TROLDBORG (M50)
FRANCOIS LHUISSIER (M35)
PETER KRIEGER (M34)
ANDREW YIM (M42)
CRISTIAN VALENZUELA (M27)
MARCO CAVALLUCCI (M46)
JONATHAN DROUT (M41)
SVEN WISSING (M35)
JIM CLEMENS (M46)
YVES SCHINDFESSEL (M47)
JASON BROWN (M37)
ULRICH FLUHME (M39)
MICHAEL ALBERT (M43)
JOSE LUIS BENITEZ (M29)
NATHAN AHART (M26)
LAWRENCE WARRINER (M50)
LUIS DIAS (M46)
MARIO DIMAS (M31)
RICARDO VALE (M25)
CHRIS FISHER (M35)
JOON SONG (M43)
CIARAN CANAVAN (M39)
LEIF WELHAVEN (M40)
TOM PAPAIN (M26)
NIELS DECLERCK (M26)
PHIL TEIJEIRA (M35)
JAN MUENCH (M39)
FILIPPO DE CONTO (M36)
PETER TOLLEFSON (M32)
MORTEN JEST (M40)
DOUGLAS LETTERMAN (M34)
JENS RITTER (M41)
PAUL BURTON (M50)
JOSE AGUETE (M34)
PAUL ROOME (M40)
GLEN WEISSMAN (M44)
CLIFF GERBER (M28)
JON FIVA (M35)
TODD BLANCHARD (M44)
CHRISTOPHE TREUIL (M41)
BRUNO RAINAUD (M45)
JACOB LEBLANC (M29)
[Finished in 4.1s]

与页面本身的结果相匹配,在浏览器中查看:

如果这有帮助,请告诉我们。

【讨论】:

  • Nanashi,这成功了。万分感谢。难以置信——我确实注意到了请求标头中的引用者,但认为 requests.session() 正在执行此操作!
  • 一个小提示——B 实际上是正确的。它返回男性和女性的结果。 M 只返回男性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
相关资源
最近更新 更多