2012-01-24 73 views
0

變灰的多個下拉窗體所以我試圖從Gasbuddy.com取消一些汽車信息,但我在scrapy代碼中遇到了一些麻煩。你如何處理與scrapy FormRequest

這裏是我到目前爲止,讓我知道我做錯了什麼:

from scrapy.spider import BaseSpider 
from scrapy.selector import HtmlXPathSelector 
from scrapy.contrib.loader import XPathItemLoader 
from scrapy.http import Request 
from scrapy.http import FormRequest 

class gasBuddy(BaseSpider): 
name = "gasBuddy" 
allowed_domains = ["http://www.gasbuddy.com"] 
start_urls = [ 
    "http://www.gasbuddy.com/Trip_Calculator.aspx", 
] 

def parse(self, response): 
    hxs = HtmlXPathSelector(response) 
    #for years in hxs.select('//select[@id="ddlYear"]/option/text()'): 
     #print years 
    FormRequest(url="http://www.gasbuddy.com/Trip_Calculator.aspx", 
       formdata={'Year': '%s'%("2011")}, 
       callback=self.make('2011')) 


def make (years, self, response): 
    #this is where we loop through all of the car makes and send the response to modle 
    hxs = HtmlXPathSelector(response) 
    for makes in hxs.select('//select[@id="ddlMake"]/option/text()').extract() 
     FormRequest(url="http://www.gasbuddy.com/Trip_Calculator.aspx", 
       formdata={'Year': '%s', 'Make': '%s'%(years, makes)}, 
       callback=self.model(years, makes)) 


def model (years, makes, self, response): 
    #this is where we loop through all of the car modles and get all of the data assoceated with it. 
    hxs = HtmlXPathSelector(response) 
    for models in hxs.select('//select[@id="ddlModel"]/option/text()') 
     FormRequest(url="http://www.gasbuddy.com/Trip_Calculator.aspx", 
       formdata={'Year': '%s', 'Make': '%s', 'Model': '%s'%(years, makes, models)}, 
       callback=self.model(years, makes)) 

     print hxs.select('//td[@id="tdCityMpg"]/text()') 

我這個代碼的基本思路是選擇一個表單字段然後再打一個formRequest並有回調到另一個功能,然後繼續循環,直到我到達最後一個,然後我開始閱讀每輛車的信息。但我不斷收到一些錯誤......一個是 gasbuddy沒有屬性「編碼」(我不知道這是什麼)。 我也不確定您是否可以將周界傳遞給回調函數。

任何幫助將不勝感激。

回答

3

此答案僅涵蓋調用具有附加參數的回調方法,並不能解決具體網站的動態表單問題。

要將其他參數傳遞給回調函數,可以使用標準Python庫中的functools.partial

沒有Scrapy

簡單的例子:

import functools 


def func(self, response): 
    print self, response 

def func_with_param(self, response, param): 
    print self, response, param  

def caller(callback): 
    callback('self', 'response') 

caller(func) 
caller(functools.partial(func_with_param, param='param')) 

所以,你應該定義makemodel功能,像這樣(self始終是第一個參數):

def make (self, response, years): 
    ... 

def model (self, response, years, makes): 
    ... 

而且回調參數:

import functools 
... 

def parse(self, response): 
    ... 
    return FormRequest(url="http://www.gasbuddy.com/Trip_Calculator.aspx", 
         formdata={'Year': '%s'%("2011")}, 
         callback=functools.partial(self.make, years='2011')) 

另一種選擇來傳遞參數在Scrapy回調是使用meta論據FormRequest

例如爲:

def parse(self, response): 
    ... 
    return FormRequest(url="http://www.gasbuddy.com/Trip_Calculator.aspx", 
         formdata={'Year': '%s'%("2011")}, 
         meta={'years':'2011'}, 
         callback=self.make) 

def make (self, response): 
    years = response.meta['years'] 
    ... 

而且similiar爲models

您的代碼中的另一個問題FormRequest只是創建和不使用。你應該(在我parse例如等)或yield他們返回他們的循環:

for something in hxs.select(...).extract(): 
    yield FormRequest(...) 
+0

非常感謝你對這種深入的解釋。這非常有幫助。你是我的英雄。 :) –

+0

@ AlexW.H.B。試圖做類似的事情,你能分享你如何解決這個問題嗎?新的python,但如果你分享你的代碼,我可能會明白,因爲有PHP背景。 –