2014-03-01 37 views
1

我想使用scrapy來廣泛地使用javascript來操縱文檔,cookies等(但沒有簡單的像JSON響應)。出於某種原因,我無法從網絡流量中確定,當我在瀏覽器中查看時,我需要的頁面會顯示爲錯誤,但不會顯示。所以我想要做的就是使用webkit來呈現瀏覽器中顯示的頁面,然後對其進行刮除。 scrapyjs項目是爲此目的而製作的。Scrapy使用完整的webkit管理會話cookie javascript執行

要訪問我需要的頁面,我必須先登錄並保存了一些會話cookie。我的問題是,當它呈現頁面時,我無法成功向Webkit提供會話cookie。有兩種方式我可以這樣做:

  1. 獨家使用scrapy頁面請求,直到我到達需要webkit的頁面,然後傳遞必需的cookie。
  2. 在scrapy中使用webkit(通過scrapyjs的修改版本),從登錄到整個會話,直到我需要的頁面,並允許它根據需要保留cookie。

不幸的是,這兩種方法似乎都沒有奏效。

沿方法1中的線,我嘗試以下: 在settings.py -

DOWNLOADER_MIDDLEWARES = { 
    'scrapyjs.middleware.WebkitDownloader': 701, #to run after CookiesMiddleware 
} 

我改性scrapyjs發送cookie:scrapyjs/middleware.py--

import gtk 
import webkit 
import jswebkit 
#import gi.repository import Soup # conflicting static and dynamic includes!? 
import ctypes 
libsoup = ctypes.CDLL('/usr/lib/i386-linux-gnu/libsoup-2.4.so.1') 
libwebkit = ctypes.CDLL('/usr/lib/libwebkitgtk-1.0.so.0') 

def process_request(self, request, spider): 
    if 'renderjs' in request.meta: 
     cookies = request.headers.getlist('Cookie') 
     if len(cookies)>0: 
      cookies = cookies[0].split('; ') 
      cookiejar = libsoup.soup_cookie_jar_new() 
      libsoup.soup_cookie_jar_set_accept_policy(cookiejar,0) #0==ALWAYS ACCEPT 
      up = urlparse(request.url) 
      for c in cookies: 
       sp=c.find('=') # find FIRST = as split position 
       cookiename = c[0:sp]; cookieval = c[sp+1:]; 
       libsoup.soup_cookie_jar_add_cookie(cookiejar, libsoup.soup_cookie_new(cookiename,cookieval,up.hostname,'None',-1)) 
       session = libwebkit.webkit_get_default_session() 
       libsoup.soup_session_add_feature(session,cookiejar) 

     webview = self._get_webview() 
     webview.connect('load-finished', self.stop_gtk) 
     webview.load_uri(request.url) 
     ... 

設置cookiejar的代碼是從this response改編的。問題可能在於進口如何工作;也許這不是我正在修改的正確的webkit - 我對webkit不太熟悉,而python文檔也很差。 (我不能在第二個答案的方法中使用from gi.repository import Soup,因爲它混合了靜態和動態庫。我也無法在上面導入的webkit中找到任何get_default_session())。

第二種方法失敗,因爲跨請求不保留會話,並且我對webkit知之甚少,無法知道如何使其保留在此框架中。

任何幫助表示讚賞!

回答

0

實際上,第一種方法確實是的工作,但有一個修改。 Cookie的路徑必須是「/」(至少在我的應用程序中),而不是上面代碼中的「無」。也就是說,該行應該是

libsoup.soup_cookie_jar_add_cookie(cookiejar, libsoup.soup_cookie_new(cookiename,cookieval,up.hostname,'/',-1)) 

不幸的是,這隻能將問題推回一點點。現在cookies已經正確保存,但整個頁面(包括框架)仍然沒有像我期望的那樣使用webkit加載和呈現,所以DOM沒有完成,因爲我在瀏覽器中看到它。如果我只是簡單地請求我想要的框架,那麼我會得到錯誤頁面而不是實際瀏覽器中顯示的內容。我很想看看如何使用webkit來渲染整個頁面,包括框架。或者如何實現第二種方法,在webkit中完成整個會話。

0

不知道Ithe應用程序的完整工作流程,您需要確保設置cookie jar發生在webkit完成任何其他網絡活動之前。 http://webkitgtk.org/reference/webkitgtk/unstable/webkitgtk-Global-functions.html#webkit-get-default-session。根據我的經驗,這實際上意味着甚至在實例化Web視圖之前。

要檢查的另一件事是,如果您的框架來自相同的域名.Cookie策略將不允許跨不同域名的Cookie。

最後,您可以注入cookie。請參閱http://webkitgtk.org/reference/webkitgtk/unstable/webkitgtk-webkitwebview.html#WebKitWebView-navigation-policy-decision-requested或資源請求啓動,然後在實際的湯信息上設置cookie。