2016-11-07 104 views
1

我正在爬行一個網站,它有JavaScript轉到下一頁。我正在使用splash在第一頁上執行我的JavaScript代碼。但我能夠去第二頁。但我無法去3,4,5 ....頁面。爬網僅在一頁後停止。遞歸爬行使用javascript與scrapy和splash的相同頁面

的鏈接,我爬: http://59.180.234.21:8788/user/viewallrecord.aspx

代碼:

import scrapy 
from scrapy_splash import SplashRequest 
from time import sleep 


class MSEDCLSpider(scrapy.Spider): 
    name = "msedcl_spider" 
    scope_path = 'body > table:nth-child(11) tr > td.content_area > table:nth-child(4) tr:not(:first-child)' 
    ref_no_path = "td:nth-child(1) ::text" 
    title_path = "td:nth-child(2) ::text" 
    end_date_path = "td:nth-child(5) ::text" 
    fee_path = "td:nth-child(6) ::text" 
    start_urls = ["http://59.180.234.21:8788/user/viewallrecord.aspx"] 

    lua_src = """function main(splash) 
     local url = splash.args.url 
     splash:go(url) 
     splash:wait(2.0) 
     splash:runjs("document.querySelectorAll('#lnkNext')[0].click()") 
     splash:wait(4.0) 
     return { 
      splash:html(), 
     } 
     end 
     """ 

    def start_requests(self): 
     for url in self.start_urls: 
      yield SplashRequest(
       url, 
       self.parse, 
       endpoint='execute', 
       method='POST', 
       dont_filter=True, 
       args={ 
        'wait': 1.0, 
        'lua_source': self.lua_src, 
       }, 
      ) 


    def parse(self, response): 
     print response.status 
     scopes = response.css('#page-info').extract()[0] 
     print(response.url) 
     print(scopes) 

我是新手既scrapy和飛濺。請溫柔。謝謝

+0

主代碼中沒有縮進問題。當我粘貼代碼時,它被改變了。 –

+0

我認爲你在混合空格和製表符(至少在粘貼的代碼中)。嘗試使用所有空格(每個選項卡4個空格)來格式化問題中的代碼。 –

+0

問題不在於縮進。任何我編輯後的方式,並修改它 –

回答

2

我可以看到兩個問題:

  1. 你最好不要讓這些請求。在start_requests中發出一個請求,響應在self.parse方法中被解析,但對第三個和其他頁面的請求從不發送。爲此,您需要從.parse方法發送一些請求。

  2. 如果修復(1),那麼你很可能會面臨下一個問題:啓動不保留請求之間的頁面狀態。將每個請求視爲打開一個新的Private Mode瀏覽器窗口並執行一些操作;這是設計。但是這個網站的問題在於URL不會在頁面之間改變,所以你不能只是開始從第3頁開始,點擊「下一頁」。

但我認爲有辦法解決方法(2)。也許你可以點擊後獲取頁面html,然後使用splash:set_content將其加載到瀏覽器;你也可以保存餅乾 - 在scrapy-splash README中有一個例子;雖然它似乎並沒有依靠cookies來進行分頁。

另一種方式是寫一個加載的所有頁面,不僅翻頁,然後返回所有網頁到客戶端的腳本的內容。像這樣(未經測試):

function main(splash) 
    splash:go(splash.args.url) 
    local pages = {splash:html()} 
    for i = 2,100 do    
     splash:runjs("document.querySelectorAll('#lnkNext')[0].click()")    
     splash:wait(4) 
     pages[i] = splash:html() 
    end 
    return pages 
end 

爲了這個工作,你需要一個更大的超時值;您可能還必須使用更大的--max-timeout選項啓動Splash。

+0

感謝您的答案。第二種方法有什麼缺點?如性能,內存使用等,因爲有一些其他網站有超過200頁的爬行。 –

+0

@REDDYPRASAD第二種方法很難監視和調試,並且如果發生錯誤,您將無法獲得部分結果並繼續執行(除非您已經以處理該腳本的方式編寫腳本)。 –