2015-02-27 4 views
1

Чтобы очистить конкретный веб-сайт за 180 дней в будущем, необходимо получить токен аутентификации, чтобы получить данные json для очистки. При очистке токен истекает, и ответ HTTP возвращает код состояния 401 «Несанкционированный». Как мне получить новый токен в скребок и продолжить очищение? Любая помощь приветствуется.Scrap - аутентифицированный токен аутентификации веб-сайта истекает при очистке

def start_requests(self): 
    return [Request(url=AUTHORIZATION_URL, callback=self.request_ride_times)] 

def request_ride_times(self, response): 
    # parse json data 
    data = json.loads(response.body) 

    # get auth token 
    auth = '{}'.format(data['access_token']) 

    # set auth token in headers 
    headers = {'Authorization': 'BEARER {}'.format(auth)} 

    # note: this probably isn't really necessary but it doesn't hurt (all the sites times we are scraping are in EST) 
    now = get_current_time_for_timezone("US/Eastern") 

    # get ending timeframe for scraping dates - 190 days out 
    until = now + SCRAPE_TIMEFRAME 

    for filter_type in FILTER_TYPES: 
     filter_url_query_attr = '&filters={}'.format(filter_type) 

     scrape_date = now 

     while scrape_date <= until: 
      url = urljoin(SCRAPE_BASE_URL, '{}{}&date={}'.format(SCRAPE_BASE_URL_QUERY_STRING, filter_url_query_attr, scrape_date.strftime("%Y-%m-%d"))) 
      yield Request(url, headers=headers, callback=self.parse_ride_times, errback=self.error_handler) 

      scrape_date += timedelta(days=1) 

def parse_ride_times(self, response): 
    # parse json data 
    data = json.loads(response.body) 

    for index, ride_details in enumerate(data['results']): 

     if 'schedule' not in ride_details: 
      continue 

     ride_schedule = ride_details['schedule'] 

     # create item... 

      yield item 
+0

Я смеялся, когда я увидел * 180 дней в будущее * –

+0

На сайте есть расписание с сегодняшнего дня через 180 дней с сегодняшнего дня. Я хочу получать данные о расписании за каждый день. Имеет ли это смысл? – groovesocket

+0

Я понимаю, я просто подумал, что это смешно. Как вы сначала аутентифицируетесь? –

ответ

1

Я смог понять это. Мне пришлось переопределить объект Request, чтобы установить новый токен авторизации в заголовок, когда истекает срок действия токена. Я сделал маркер глобальной переменной.

# override Request object in order to set new authorization token into the header when the token expires   
authorization_token = None 

class AuthTokenRequest(Request): 
    @property 
    def headers(self): 
     global authorization_token 
     return Headers({'Authorization': 'BEARER {}'.format(authorization_token)}, encoding=self.encoding) 

    @headers.setter 
    def headers(self, value): 
     pass 

Переопределенный запрос затем используется в запросе, в то время цикла включая errback функции error_handler, которая вызывается, когда запрос не выполняется. Функция error_handler получает новый токен, сбрасывает глобальную переменную токена и затем повторно передает запрос с новым токеном. В том же запросе параметр dont_filter был установлен в False, поэтому запрос на неудачу может быть переработан.

Были созданы еще две функции. Один вызванный handle_auth был создан, чтобы первоначально установить токен в глобальной переменной. Другой - start_first_run, который вызывает handle_auth и возвращает функцию request_ride_times. Это вызывается в запросе start_requests.

def error_handler(self, failure): 
    global authorization_token 
    status = failure.value.response.status 
    if status == 401: 
     form_data = {'grant_type': 'assertion', 'assertion_type': 'public', 'client_id': 'WDPRO-MOBILE.CLIENT-PROD'} 
     auth_site_request = requests.post(url=AUTHORIZATION_URL, data=form_data) 
     auth_site_response = json.loads(auth_site_request.text) 
     disney_authorization_token = '{}'.format(auth_site_response['access_token']) 

     yield failure.request 

def start_requests(self): 
    form_data = {'grant_type': 'assertion', 'assertion_type': 'public', 'client_id': 'WDPRO-MOBILE.CLIENT-PROD'} 
    return [FormRequest(url=AUTHORIZATION_URL, formdata=form_data, 
         callback=self.start_first_run)] 

def start_first_run(self, response): 
    self.handle_auth(response) 
    return self.request_ride_times() 

def handle_auth(self, response): 
    global authorization_token 

    data = json.loads(response.body) 

    # get auth token 
    authorization_token = '{}'.format(data['access_token']) 

def request_ride_times(self): 
    # note: this probably isn't really necessary but it doesn't hurt (all the sites we are scraping are in EST) 
    now = get_current_time_for_timezone("US/Eastern") 

    # get ending timeframe for scraping dates - 190 days out 
    until = now + SCRAPE_TIMEFRAME 

    for filter_type in FILTER_TYPES: 
     filter_url_query_attr = '&filters={}'.format(filter_type) 

     scrape_date = now 

     while scrape_date <= until: 
      url = urljoin(SCRAPE_BASE_URL, 
          '{}{}&date={}'.format(SCRAPE_BASE_URL_QUERY_STRING, 
               filter_url_query_attr, scrape_date.strftime("%Y-%m-%d"))) 
      yield AuthTokenRequest(url, callback=self.parse_ride_times, errback=self.error_handler, dont_filter=True, 
           meta={"scrape_date": scrape_date}) 

      scrape_date += timedelta(days=1) 

def parse_ride_times(self, response): 
    # parse json data 
    data = json.loads(response.body) 
    # process data... 
Смежные вопросы