2013-07-25 103 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無頭網頁瀏覽。