How do I close pop-up windows with Selenium in Python when I don't know when they will pop up?

I am trying to scrape historical weather data from this website: https://www.worldweatheronline.com/taoyuan-weather-history/tai-wan/tw.aspx

Using this code:

    driver.find_element_by_css_selector("input[type='date']").send_keys(str(for_weather.mm[i])+str(for_weather.dd[i])+for_weather.year[i].astype(str))

wait=WebDriverWait(driver,10)
wait.until(EC.element_to_be_clickable((By.ID,'ctl00_MainContentHolder_butShowPastWeather'))).click()
temp=driver.find_element_by_xpath('//div[@class="days-collapse-temp"]').get_attribute('innerHTML')

One some of the pages, a popup appears. Screenshot of the popup

I've seen help that shows how to choose and close popups, but in my case, we don't know when they will show up. On some pages it appears, some don't. When they do show up, they prevent me from obtaining the data I want, and stops the loop. The following is the error message (it has the characteristics of the popup):

ElementClickInterceptedException: element click intercepted: Element <input type="submit" name="ctl00$MainContentHolder$butShowPastWeather" value="Get Weather" id="ctl00_MainContentHolder_butShowPastWeather" class="btn btn-success ml-2"> is not clickable at point (956, 559). Other element would receive the click: <div class="introjs-overlay" style="inset: 0px; position: fixed; cursor: pointer;"></div>
  (Session info: chrome=97.0.4692.71)

Thanks much!


Solution 1:

Here's a Python Selenium solution that uses SeleniumBase:

First pip install seleniumbase, then copy the example below into a Python file, eg weather_test.py. Then run it with pytest:

pytest weather_test.py --block-ads

from seleniumbase import BaseCase

class MyTestClass(BaseCase):
    def test_base(self):
        self.open("https://www.worldweatheronline.com/taoyuan-weather-history/tai-wan/tw.aspx")
        self.js_click("#ctl00_MainContentHolder_butShowPastWeather")
        for i in range(1, 32):
            date_string = "2021-12-%s" % i
            self.set_attribute("#datePicker input", "value", date_string)
            self.js_click('input[value="Get Weather"]')
            temp = self.get_attribute("div.days-collapse-temp", "innerHTML")
            temp = temp.split("</span>")[-1]
            print("%s : %s" % (date_string, temp))

That will get you the weather in that city for all days in December:

2021-12-1 : 11°/13°c
2021-12-2 : 11°/13°c
2021-12-3 : 11°/13°c
2021-12-4 : 11°/13°c
2021-12-5 : 11°/13°c
2021-12-6 : 11°/13°c
2021-12-7 : 11°/13°c
2021-12-8 : 11°/13°c
2021-12-9 : 11°/13°c
2021-12-10 : 17°/21°c
2021-12-11 : 17°/25°c
2021-12-12 : 17°/20°c
2021-12-13 : 14°/15°c
2021-12-14 : 15°/23°c
2021-12-15 : 15°/28°c
2021-12-16 : 17°/27°c
2021-12-17 : 12°/18°c
2021-12-18 : 11°/13°c
2021-12-19 : 12°/18°c
2021-12-20 : 15°/18°c
2021-12-21 : 16°/18°c
2021-12-22 : 17°/18°c
2021-12-23 : 16°/19°c
2021-12-24 : 16°/21°c
2021-12-25 : 13°/14°c
2021-12-26 : 9°/12°c
2021-12-27 : 9°/11°c
2021-12-28 : 10°/18°c
2021-12-29 : 14°/17°c
2021-12-30 : 12°/13°c
2021-12-31 : 11°/14°c

The key difference is that it uses js_click to click on things instead of a regular click, which would give you a ElementClickInterceptedException if there was a pop-up.