scraping - selenium webdriver python
Pantalla raspando un Datepicker con Scrapy y Selenium en el mouse sobre el mouse (2)
Así que tengo que eliminar una página como esta, por ejemplo, y estoy usando Scrapy + Seleninum para interactuar con un calendario de citas.
Me di cuenta de que si hay una fecha determinada disponible, aparece un precio en la información sobre herramientas, y si no está disponible si pasas el cursor sobre ella, no ocurre nada.
¿Cuál es el código para que obtenga el precio que aparece dinámicamente cuando pasas el mouse sobre un día disponible y también cómo sé si está disponible o no solo con el elemento emergente?
Hola, por favor encuentra la respuesta
Nota clave: hemos esperado unos segundos después de hacer clic en el evento en el calendario, porque java-script toma el tiempo de procesamiento interno en el calendario después de que se abre.
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver","D://eclipseProject////chromedriver_win32 (1)//chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.manage().window().maximize();
Actions act = new Actions(driver);
WebDriverWait wait = new WebDriverWait(driver,30);
driver.get("https://www.airbnb.pt/rooms/265820?check_in=2016-04-26&guests=1&check_out=2016-04-29");
// selecting firstdate picker -- check in
driver.findElement(By.xpath("//*[@class=''col-sm-6'']/input")).click();
// NOTE: we have to give sleep due to java-script takes internal processing time on calendar after it get opens
Thread.sleep(5000);
// NOTE: calendar is not completely visible hence to make it visible
// scroll a little bit down
((JavascriptExecutor) driver).executeScript("window.scrollBy(0,200)");
// take all calendar dates inside the list
List<WebElement> myhAvDates = driver.findElements(By.xpath("//*[@class=''ui-datepicker-calendar'']/tbody/tr/td/a[contains(@class, ''ui-state-default'')]"));
System.out.println("Size is "+myhAvDates.size());
for(int i=0;i<myhAvDates.size();i++){
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[@class=''ui-datepicker-calendar'']/tbody/tr/td/a")));
System.out.println("Available Date is : " + myhAvDates.get(i).getText());
act.moveToElement(myhAvDates.get(i)).build().perform();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".datepicker-tooltip")));
WebElement toolTipElement = driver.findElement(By.cssSelector(".datepicker-tooltip"));
System.out.println("Available Date is : " + myhAvDates.get(i).getText() + "==" +"And price is "+ toolTipElement.getText());
myhAvDates = driver.findElements(By.xpath("//*[@class=''ui-datepicker-calendar'']/tbody/tr/td/a"));
}
}
el código anterior dará respuesta como
Size is 10
Available Date is : 13
Available Date is : 13==And price is €40
Available Date is : 19
Available Date is : 19==And price is €36
Available Date is : 20
Available Date is : 20==And price is €49
Available Date is : 22
Available Date is : 22==And price is €49
Available Date is : 25
Available Date is : 25==And price is €40
Available Date is : 26
Available Date is : 26==And price is €39
Available Date is : 27
Available Date is : 27==And price is €35
Available Date is : 28
Available Date is : 28==And price is €37
Available Date is : 29
Available Date is : 29==And price is €37
Available Date is : 30
Available Date is : 30==And price is €37
No es tan fácil cómo abordar el problema debido a la naturaleza dinámica de la página: debe usar esperas aquí y allá, y es difícil captar el código HTML de los componentes dinámicos que aparecen al hacer clic o al desplazarse.
Aquí está el código de trabajo completo que se desplazará a la página, haga clic en la entrada "Registrar", espere a que se cargue el calendario e informe la disponibilidad para cada uno de los días en el calendario (utiliza la presencia de ui-datepicker-unselectable
clase para determinar eso). Luego, desplaza cada celda con la acción del navegador move_to_element()
, espera la información sobre herramientas y obtiene el precio:
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("https://www.airbnb.pt/rooms/265820?check_in=2016-04-26&guests=1&check_out=2016-04-29")
# wait for the check in input to load
wait = WebDriverWait(driver, 10)
elem = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.book-it-panel input[name=checkin]")))
elem.click()
# wait for datepicker to load
wait.until(
EC.visibility_of_element_located((By.CSS_SELECTOR, ''.ui-datepicker:not(.loading)''))
)
days = driver.find_elements_by_css_selector(".ui-datepicker table.ui-datepicker-calendar tr td")
for cell in days:
day = cell.text.strip()
if not day:
continue
if "ui-datepicker-unselectable" in cell.get_attribute("class"):
status = "Unavailable"
else:
status = "Available"
price = "n/a"
if status == "Available":
# hover the cell and wait for the tooltip
ActionChains(driver).move_to_element(cell).perform()
price = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ''.datepicker-tooltip''))).text
print(day, status, price)
Huellas dactilares:
1 Unavailable n/a
2 Unavailable n/a
3 Unavailable n/a
4 Unavailable n/a
5 Unavailable n/a
6 Unavailable n/a
7 Unavailable n/a
8 Unavailable n/a
9 Unavailable n/a
10 Unavailable n/a
11 Unavailable n/a
12 Unavailable n/a
13 Available €40
14 Unavailable n/a
15 Unavailable n/a
16 Unavailable n/a
17 Unavailable n/a
18 Unavailable n/a
19 Available €36
20 Available €49
21 Unavailable n/a
22 Available €49
23 Unavailable n/a
24 Unavailable n/a
25 Available €40
26 Available €39
27 Available €35
28 Available €37
29 Available €37
30 Available €37