как вы справляетесь с несколькими выпадающими формами, которые выделены серым с помощью scrap FormRequest - PullRequest
0 голосов
/ 24 января 2012

Итак, я пытаюсь удалить информацию об автомобиле с сайта Gasbuddy.com, но у меня возникли некоторые проблемы с кодом скрапа.

вот что у меня есть, дайте мне знать, что я делаю неправильно:

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 иперезвонить другой функции, которая затем продолжается в цикле, пока я не доберусь до последней, затем я начну читать информацию о каждой машине.но я продолжаю получать несколько ошибок ... одна из них не имеет атрибута 'encoding' (о чем я не знаю).Я также не уверен, что вы можете передавать периметры в функцию обратного вызова.

любая помощь будет принята с благодарностью.

1 Ответ

3 голосов
/ 24 января 2012

Этот ответ охватывает только способы вызова обратных вызовов с дополнительными аргументами и не решает проблему с динамическими формами для вашего конкретного сайта.

Для передачи дополнительных параметров обратному вызову вы можете использовать functools.partial из стандартной библиотеки Python.

Упрощенный пример без 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'))

Таким образом, вы должны определить make и model функции, подобные этой (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']
    ...

И похоже на models.

Еще одна проблема в вашем коде, FormRequest только создаются и не используются.Вы должны вернуть их (как в моем parse примере) или yield их в цикле for:

for something in hxs.select(...).extract():
    yield FormRequest(...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...