2013-07-25 60 views
0

我想刮tripadvisor。假设我想刮坏的评论对这个特殊的酒店:屏幕抓取tripadvisor与张贴请求

http://www.tripadvisor.com/Hotel_Review-g31441-d224344-Reviews-Hilton_Garden_Inn_Bentonville-Bentonville_Arkansas.html#REVIEWS

我只是想“可怕”类别,这一选择/过滤应该由HTML表单控制。 我打算发送一份提交申请的表单。我原本想从机械化模块中使用br.submit(),但后来发现它不支持JavaScript。所以我希望使用post请求绕过javascript。

但是,当我使用机械化来查看相关控件时,单选按钮具有相同的值。 这里是我的代码:

br = mechanize.Browser() 
br.set_handle_equiv(True) 
br.set_handle_gzip(True) 
br.set_handle_redirect(True) 
br.set_handle_referer(True) 
br.set_handle_robots(False) 
br.addheaders = [('User-agent', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008071615 Fedora/3.0.1-1.fc9 Firefox/3.0.1')] 
br.open("http://www.tripadvisor.com/Hotel_Review-g31441-d224344-Reviews-Hilton_Garden_Inn_Bentonville-Bentonville_Arkansas.html#REVIEWS") 

for f in br.forms(): 
    print f 

下面是其中的相关窗体和控件:

<POST http://www.tripadvisor.com/SortReviews#REVIEWS application/x-www-form-urlencoded 
    <RadioControl(segRdo=[on, on, on, on, on])> 
    <RadioControl(comRdo=[on, on, on, on, on])> 
    <HiddenControl(returnTo=__2F__Hotel__5F__Review__2D__g31441__2D__d224344__2D__Reviews__2D__Hilton__5F__Garden__5F__Inn__5F__Bentonville__2D__Bentonville__5F__Arkansas__2E__html#REVIEWS) (readonly) 
    <HiddenControl(filterSegment=0) (readonly)> 
    <HiddenControl(filterRating=1) (readonly)>> 

所以评级由comRdo控制控制,但奇怪的是,类别,或单选按钮有相同的值'on'。 我们之前并选择其中一个类别后,看到该控件的属性:

前:

control_com=br.form.find_control("comRdo","radio") 
print control_com.name,control_com.value,control_com.type 
comRdo [] radio 

后:所以选择“可怕”类别后

(br.form.find_control("comRdo","radio")).items[4].selected=True 
print control_com.name,control_com.value,control_com.type 
comRdo ['on'] radio 

,控件的值是'如果我选择了任何其他类别,这将是相同的。当我在comRdo控件中打印项目时:只有'id是不同的,每个其他属性都是相同的:

<Item name='on' id='com1' id='com1' type='radio' class='radio' value='on' name='comRdo'> 
<Item name='on' id='com2' id='com2' type='radio' class='radio' value='on' name='comRdo'> 
... 

那么这是如何工作的?服务器如何知道我选择哪个单选按钮,因为它们都具有相同的值? 我准备了发布数据并将其发送到请求中,并且如预期的那样不起作用。 RES具有相同的内容作为一个没有任何过滤/后请求

form={"comRdo":"on"} 
req=mechanize.Request("http://www.tripadvisor.com/Hotel_Review-g31441-d224344-Reviews-Hilton_Garden_Inn_Bentonville-Bentonville_Arkansas.html#REVIEWS",urllib.urlencode(form)) 
req.add_header('Content-Type','application/x-www-form-urlencoded') 
cj.add_cookie_header(req) 
res=mechanize.urlopen(req) 

而且我也试图与其他后数据中的代码:

form={"comRdo":["on","on","on","on","on","*on"]} 

form={"filterSegment":"0","filterRating":"1"} 
莫非

有人帮我解决这个问题?这个页面如何使用相同值的单选按钮?我如何以编程方式过滤评​​论?提前致谢!


感谢斯莱特Tyranus和Diadara,我的以下代码工作!

form={"returnTo":"__2F__Hotel__5F__Review__2D__g31441__2D__d224344__2D__Reviews__2D__Hilton__5F__Garden__5F__Inn__5F__Bentonville__2D__Bentonville__5F__Arkansas__2E__html#REVIEWS","filterSegment":"0","filterRating":"1"} 
url="http://www.tripadvisor.com/SortReviews#REVIEWS" 
headers={'content-type':'application/x-www-form-urlencoded'} 
r=requests.post(url,data=form) 
soup=BeautifulSoup(r.content) 

回答

1

至于对方的回答指出,只看网络选项卡要弄清楚什么要求是浏览器making.In这种情况下在窗体中有一个以上的元素,所有的人都需出示所需的页面。所以,你应该用

所有这些值

comRdo:on 
returnTo:__2F__Hotel__5F__Review__2D__g31441__2D__d224344__2D__Reviews__2D__Hilton__5F__Garden__5F__Inn__5F__Bentonville__2D__Bentonville__5F__Arkansas__2E__html#REVIEWS 
filterSegment:0 
filterRating:1 

还你会发现,你实际上是提交到错误的URL,看看表单的操作字段或铬合金网标签

开放网络标签,点击保存日志,点击产生你的结果的链接,然后看看请求,找出你应该做什么。

+0

谢谢!但问题是,我不明白什么网络标签显示我。更具体地说,我不知道在哪里寻找后期参数。你能详细说明一下还是给我一个教程的链接? – GorillaInR

+0

行动= “/ SortReviews#点评”,但这指的是代码shoudl是: “上” “returnTo”:数据= { “comRdo” “__ 2F__Hotel__5F__Review__2D__g31441__2D__d224344__2D__Reviews__2D__Hilton__5F__Garden__5F__Inn__5F__Bentonville__2D__Bentonville__5F__Arkansas__2E__html#评测” “filterSegment”: “0” “filterRating” : “1”} requests.post( “http://www.tripadvisor.com/SortReviews#REVIEWS”,数据) – GorillaInR

+0

你可以使用官方文件https://developers.google.com/chrome-developer-tools/docs /网络,你可以找到大量tutorils对铬devtools在YouTube这样http://www.youtube.com/watch?v=nOEw9iiopwI请考虑投票向上或接受我的答案,如果你发现它有用 – Diadara

0

如果您想知道某个网站的POST请求如何工作,您应该检查Google Chrome中的元素并切换到网络选项卡。您将能够看到您的POST请求通过。

如果您单击该POST请求,您将详细了解您在POST请求中实际发送的信息。

在一个较低的水平,一旦你检查的元素,你会发现它嵌入了以下标签在另一个元素中:

onclick="document.forms.REVIEW_FILTER_FORM.filterRating.value='1';document.forms.REVIEW_FILTER_FORM.submit();" 

,这意味着你需要开始你在那的onclick方法的搜索,因为当你点击可怕的价值时,这就是实际发生的事情。

如果你正在试图做的一切都是取回数据,你不需要使用任何一种沉重的刮框架。我个人建议使用请求和lxml。在请求时,你应该发这个帖子请求的方式是:

requests.post(url, data={"filterRating":1}) 

如果你真的要处理网页上的JavaScript,那么你应该使用SeleniumCasper无头网页浏览。