2014-02-28 40 views
0

我正在嘗試抓取需要身份驗證的網頁。使用scrapy進行身份驗證遞歸爬取網頁

我面臨的問題是,登錄第一次正常工作,我獲得Successfull登錄日誌,但是當抓取工具從start_url開始抓取頁面時,它不捕獲csv中的頁面文件輸出,需要用於查看數據的登錄憑據。

我是否缺少任何東西來保留整個過程中的登錄會話或某些檢查以檢查每個需要登錄然後才能繼續的url。

我的登錄表單是一個後形式,其輸出是如下 -

2014年2月28日21:16:53 + 0000 [myspider] INFO:爬0頁(在0頁/分),刮下0的項目(在0件/分鐘)

2014年2月28日21:16:53 + 0000 [scrapy] DEBUG:遠程控制檯偵聽0.0.0.0:6023

2014年2月28日21 :16:53 + 0000 [scrapy] DEBUG:正在監聽的Web服務0.0.0.0:6080

2014-02-28 21:16:53 + 0000 [myspider] DEBUG:Crawled(200)https ://someurl.com/login_form>(referer:None)

2014-02-28 21:16:53 + 0000 [myspider] DEBUG:Crawled(200)https://someurl.com/search>(引用者:https://someurl.com/login_form

2014-02-28 21:16:53 + 0000 [myspider] DEBUG:成功登錄。開始抓取!

它會自動將搜索頁面的第一擊,而不是login_form頁面(START_URL)

請人幫我在這?

下面是我的代碼:

from scrapy.spider import BaseSpider 
from scrapy.contrib.spiders.init import InitSpider 
from scrapy.http import Request, FormRequest 
from scrapy.selector import HtmlXPathSelector 
from tutorial.items import DmozItem 
from scrapy.contrib.spiders import CrawlSpider, Rule 
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor 
import urlparse 
from scrapy import log 


class MySpider(CrawlSpider): 

     name = 'myspider' 
     allowed_domains = ['someurl.com'] 
     login_page = 'https://someurl.com/login_form' 
     start_urls = 'https://someurl.com/' 

     rules = [Rule(SgmlLinkExtractor(), follow=True, callback='parse_item')] 

     def start_requests(self): 

      yield Request(
       url=self.login_page, 
       callback=self.login, 
       dont_filter=True 
      ) 


     def login(self, response): 
      """Generate a login request.""" 
      return FormRequest.from_response(response, 
        formdata={'__ac_name': 'username', '__ac_password': 'password' }, 
        callback=self.check_login_response) 


     def check_login_response(self, response): 
      if "Sign Out" in response.body: 
       self.log("Successfully logged in. Start Crawling") 
       return Request(url=self.start_urls) 
      else: 
       self.log("Not Logged in") 


     def parse_item(self, response): 

      # Scrape data from page 
      items = [] 
      failed_urls = [] 
      hxs = HtmlXPathSelector(response) 

      urls = hxs.select('//base/@href').extract() 
      urls.extend(hxs.select('//link/@href').extract()) 
      urls.extend(hxs.select('//a/@href').extract()) 
      urls = list(set(urls)) 

      for url in urls : 

       item = DmozItem() 

       if response.status == 404: 
        failed_urls.append(response.url) 
        self.log('failed_url : %s' % failed_urls) 
        item['failed_urls'] = failed_urls 
       else : 

        if url.startswith('http') : 
         if url.startswith('https://someurl.com'): 
          item['internal_link'] = url 
          self.log('internal_link : %s ' % url) 
         else : 
          item['external_link'] = url 
          self.log('external_link : %s ' % url) 

       items.append(item) 

      items = list(set(items)) 
      return items 

回答

0

可以使用FormRequest功能通過認證與Scrapy,這樣的:

scrapy.FormRequest(
     self.start_urls[0], 
     formdata={'LoginForm[username]':username_scrapy, 'LoginForm[password]':password_scrapy,'yt0': 'Login'}, 
     headers=self.headers) 

LoginForm的[用戶名],LoginForm的[密碼]用於通過登錄表單