用于抓取的浏览器自动化:由于下拉/自动完成输入框而导致页面不可能?

时间:2017-07-18 10:52:39

标签: javascript python selenium web-scraping

我正在试图为论文项目抓取飞行数据。具体来自STA Travel。我没有太多的经验,但我过去和其他页面做过类似的小事,从来没有遇到过问题。但是,在制作这个页面时,某些事情(许多事情?)使得这项任务看似不可能。

到目前为止我尝试过:

  • Python和Selenium与Chrome,Geckodriver(Mozilla)和PhantomJS
  • 使用CasperJS和PhantomJS的Javascript

使用CasperJS和Phantom JS,我甚至无法使用here给出的简短且看似直截了当的代码来填充第一个文本框。

使用Python和Selenium,我得到了更多,但据我所知,它全部失败的主要原因是由于输入框的实现。只要您在其中输入内容,就会打开一个动态下拉菜单,其中会显示自动填充结果。如果您没有正确单击其中一个,只需在键入后单击该框,该框将自动清除其文本。这些东西感觉像编程相当于上油的肥皂 - 无论你如何抓住它们,它们都会失控。

为了演示,这里有一些简单的可运行代码(假设您安装了Python,Selenium和geckodriver)。

# import selenium driver and helpers
from selenium import webdriver

# set browser driver
driver = webdriver.Firefox()

# open url
driver.get(url)
driver.implicitly_wait(30)

# select forms
depart_input = driver.find_element_by_css_selector(".flight_depart_location.ui-autocomplete-input")
destin_input = driver.find_element_by_css_selector(".flight_arrive_location.ui-autocomplete-input")

# send text
depart_input.send_keys(u"Zürich, Schweiz, ZRH")
destin_input.send_keys(u"Peking Int'l Apt, China, PEK")

你会看到,第一个输入在第二个输入被填写后再次被删除。我已经尝试了所有可以在网上找到的技巧,比如通过点击设置活动元素,只需发送Keys.ENTER / RETURN从一个盒子到另一个盒子。但这个网站对我来说似乎是“不可自然的”。而且我确信解决方案可能并不那么难,但我自己也找不到。因此,如果有人知道如何自动化和抓取这个页面,我会非常感激。无论解决方案如何(Python,Javascript ......别的)。

谢谢!

1 个答案:

答案 0 :(得分:0)

您要做的是输入足够的位置以使下拉列表显示在所需的位置。然后,您可以查找包含所需位置的A标记,然后单击它。你可以为抵达和离开区域做到这一点。你可能会重复使用的任何类似的东西应该放入一个函数中。

由于你用任何语言提出这个要求,我都会用Java给你。你应该可以很容易地将它翻译成python。

功能

public static void setArrival(String arrival)
{
    driver.findElement(By.cssSelector(".flight_arrive_location.ui-autocomplete-input")).sendKeys(arrival);
    new WebDriverWait(driver, 3).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'" + arrival + "')]"))).click();
}

public static void setDeparture(String departure)
{
    driver.findElement(By.cssSelector(".flight_depart_location.ui-autocomplete-input")).sendKeys(departure);
    new WebDriverWait(driver, 3).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'" + departure + "')]")))
            .click();
}

脚本

String arrivalLocation = "Peking";
String departureLocation = "Zürich";
setDeparture(departureLocation);
setArrival(arrivalLocation);