2015-06-19 3 views
2

Я пытаюсь скопировать некоторые данные со страницы поиска рейсов.Медленная прокрутка страницы с использованием Selenium

Эта страница работает следующим образом:

Вы заполнить форму, а затем вы нажмете на кнопку поиска - это нормально. Когда вы нажимаете кнопку, вы перенаправляетесь на страницу с результатами, и вот в чем проблема. Эта страница постоянно добавляет результаты, например, в течение одной минуты, что немаловажно - проблема заключается в том, чтобы получить все эти результаты. Когда вы находитесь в реальном браузере, вам нужно прокрутить страницу вниз, и эти результаты появятся. Поэтому я попытался прокрутить вниз, используя Selenium. Он прокручивается вниз в нижней части страницы, вероятно, так быстро или это прыжок вместо прокрутки, что страница не загружает никаких новых результатов.

Когда вы медленно прокручиваетесь, он перезагружает результаты, но если вы делаете это очень быстро, он прекращает загрузку.

Я не уверен, что мой код помогает понять это, поэтому я его прикрепляю.

SEARCH_STRING = """URL""" 

class spider(): 

    def __init__(self): 
     self.driver = webdriver.Firefox() 

    @staticmethod 
    def prepare_get(dep_airport,arr_airport,dep_date,arr_date): 
     string = SEARCH_STRING%(dep_airport,arr_airport,arr_airport,dep_airport,dep_date,arr_date) 
     return string 


    def find_flights_html(self,dep_airport, arr_airport, dep_date, arr_date): 
     if isinstance(dep_airport, list): 
      airports_string = str(r'%20').join(dep_airport) 
      dep_airport = airports_string 

     wait = WebDriverWait(self.driver, 60) # wait for results 
     self.driver.get(spider.prepare_get(dep_airport, arr_airport, dep_date, arr_date)) 
     wait.until(EC.invisibility_of_element_located((By.XPATH, '//img[contains(@src, "loading")]'))) 
     wait.until(EC.invisibility_of_element_located((By.XPATH, u'//div[. = "Poprosíme o trpezlivosť, hľadáme pre Vás ešte viac letov"]/preceding-sibling::img'))) 
     self.driver.execute_script("window.scrollTo(0,document.body.scrollHeight);") 

     self.driver.find_element_by_xpath('//body').send_keys(Keys.CONTROL+Keys.END) 
     return self.driver.page_source 

    @staticmethod 
    def get_info_from_borderbox(div): 
     arrival = div.find('div',class_='departure').text 
     price = div.find('div',class_='pricebox').find('div',class_=re.compile('price')) 
     departure = div.find_all('div',class_='departure')[1].contents 
     date_departure = departure[1].text 
     airport_departure = departure[5].text 
     arrival = div.find_all('div', class_= 'arrival')[0].contents 
     date_arrival = arrival[1].text 
     airport_arrival = arrival[3].text[1:] 
     print 'DEPARTURE: ' 
     print date_departure,airport_departure 
     print 'ARRIVAL: ' 
     print date_arrival,airport_arrival 

    @staticmethod 
    def get_flights_from_result_page(html): 

     def match_tag(tag, classes): 
      return (tag.name == 'div' 
        and 'class' in tag.attrs 
        and all([c in tag['class'] for c in classes])) 

     soup = mLib.getSoup_html(html) 
     divs = soup.find_all(lambda t: match_tag(t, ['borderbox', 'flightbox', 'p2'])) 

     for div in divs: 
      spider.get_info_from_borderbox(div) 

     print len(divs) 


spider_inst = spider() 

print spider.get_flights_from_result_page(spider_inst.find_flights_html(['BTS','BRU','PAR'], 'MAD', '2015-07-15', '2015-08-15')) 

Таким образом, основная проблема заключается в том, что она прокручивается слишком быстро, чтобы вызвать новую загрузку результатов.

Есть ли у вас какие-либо идеи, как заставить его работать?

ответ

1

Вот другой подход, который работал на меня с участием прокрутки в поле зрения результата последнего поиска и ждет дополнительных элементов для загрузки перед прокруткой снова:

# -*- coding: utf-8 -*- 
from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.common.exceptions import StaleElementReferenceException 
from selenium.webdriver.support import expected_conditions as EC 


class wait_for_more_than_n_elements(object): 
    def __init__(self, locator, count): 
     self.locator = locator 
     self.count = count 

    def __call__(self, driver): 
     try: 
      count = len(EC._find_elements(driver, self.locator)) 
      return count >= self.count 
     except StaleElementReferenceException: 
      return False 


driver = webdriver.Firefox() 

dep_airport = ['BTS', 'BRU', 'PAR'] 
arr_airport = 'MAD' 
dep_date = '2015-07-15' 
arr_date = '2015-08-15' 

airports_string = str(r'%20').join(dep_airport) 
dep_airport = airports_string 

url = "https://www.pelikan.sk/sk/flights/list?dfc=C%s&dtc=C%s&rfc=C%s&rtc=C%s&dd=%s&rd=%s&px=1000&ns=0&prc=&rng=1&rbd=0&ct=0" % (dep_airport, arr_airport, arr_airport, dep_airport, dep_date, arr_date) 
driver.maximize_window() 
driver.get(url) 

wait = WebDriverWait(driver, 60) 
wait.until(EC.invisibility_of_element_located((By.XPATH, '//img[contains(@src, "loading")]'))) 
wait.until(EC.invisibility_of_element_located((By.XPATH, 
               u'//div[. = "Poprosíme o trpezlivosť, hľadáme pre Vás ešte viac letov"]/preceding-sibling::img'))) 

while True: # TODO: make the endless loop end 
    results = driver.find_elements_by_css_selector("div.flightbox") 
    print "Results count: %d" % len(results) 

    # scroll to the last element 
    driver.execute_script("arguments[0].scrollIntoView();", results[-1]) 

    # wait for more results to load 
    wait.until(wait_for_more_than_n_elements((By.CSS_SELECTOR, 'div.flightbox'), len(results))) 

Примечания:

  • вам нужно будет выяснить, когда остановить цикл - например, при определенном len(results) значение
  • wait_for_more_than_n_elements - custom Expected Condition, который помогает идентифицировать, когда загружается следующая часть, и мы можем снова прокрутиться
+0

Боюсь, что это не сработает. Он возвращает 10 в цикле и когда я попытался поместить это: для результата в результатах: print result.text Я узнал, что он возвращает те же значения. –

+0

@ Милан хорошо, я вижу, что количество результатов увеличивается с каждой итерацией цикла, что означает, что дополнительные результаты загружаются. Извлеките результаты после завершения цикла. – alecxe

+0

Чтобы проверить, найдет ли он новые результаты, я добавляю результаты в набор и в каждую длину печати цикла. Он остается на 15. Здесь вы можете найти код и результаты печати: http://pastebin.com/fkUrCvAm –

Смежные вопросы