尝试编写一个小刮刀来提取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进行辩论只是为了模仿用户体验,但我确信我的请求代码中存在一些轻微的遗漏。
修改:根据反馈我已更新问题以反映我的实际代码。
答案 0 :(得分: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]
在浏览器中查看的内容与页面本身的结果相符:
如果有帮助,请告诉我们。