Skip to content

Marina Mele's site

Reflections on family, values, and personal growth

Menu
  • Home
  • About
Menu

Selenium Tutorial: Web Scraping with Selenium and Python

Posted on February 21, 2015 by Marina Mele

Imagine what would you do if you could automate all the repetitive and boring activities you perform using internet, like checking every day the first results of Google for a given keyword, or download a bunch of files from different websites.

In this post you’ll learn to use Selenium with Python, a Web Scraping tool that simulates a user surfing the Internet. For example, you can use it to automatically look for Google queries and read the results, log in to your social accounts, simulate a user to test your web application, and anything you find in your daily live that it’s repetitive. The possibilities are infinite! 🙂

*All the code in this post has been tested with Python 2.7 and Python 3.4.

Install and use Selenium

Selenium is a python package that can be installed via pip. I recommend that you install it in a virtual environment (using virtualenv and virtualenvwrapper).

No virtualenv or virtualenvwrapper?

Learn how to create one here, for Python 2.7 and for Python 3. It’s really useful, once you start using them you won’t stop! 🙂

Remember that to create the environment in Python 2.7, just type:

$ mkvirtualenv selenium_env

and in Python 3:

$ mkvirtualenv --python=/usr/local/bin/python3 selenium_env

where you should use your own Python 3 path.

Note: if you don’t want to use a virtual environment, you can still install the packages directly on you computer.

To install selenium, you just need to type:

$ pip install selenium

In this post we are going to initialize a Firefox driver — you can install it by visiting their website. However, if you want to work with Chrome or IE, you can find more information here.

Once you have Selenium and Firefox installed, create a python file, selenium_script.py. We are going to initialize a browser using Selenium:

import time
from selenium import webdriver

driver = webdriver.Firefox()
time.sleep(5)
driver.quit()

This just initializes a Firefox instance, waits for 5 seconds, and closes it.

Well, that was not very useful…

How about if we go to Google and search for something?

Web Scraping Google with Selenium

Let’s make a script that loads the main Google search page and makes a query to look for “Selenium”:

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException


def init_driver():
    driver = webdriver.Firefox()
    driver.wait = WebDriverWait(driver, 5)
    return driver


def lookup(driver, query):
    driver.get("http://www.google.com")
    try:
        box = driver.wait.until(EC.presence_of_element_located(
            (By.NAME, "q")))
        button = driver.wait.until(EC.element_to_be_clickable(
            (By.NAME, "btnK")))
        box.send_keys(query)
        button.click()
    except TimeoutException:
        print("Box or Button not found in google.com")


if __name__ == "__main__":
    driver = init_driver()
    lookup(driver, "Selenium")
    time.sleep(5)
    driver.quit()

In the previous code:

  • the function init_driver  initializes a driver instance.
    • creates the driver instance
    • adds the WebDriverWait function as an attribute to the driver, so it can be accessed more easily. This function is used to make the driver wait a certain amount of time (here 5 seconds) for an event to occur.
  • the function lookup  takes two arguments: a driver instance and a query lookup (a string).
    • it loads the Google search page
    • it waits for the query box element to be located and for the button to be clickable. Note that we are using the WebDriverWait function to wait for these elements to appear.
    • Both elements are located by name. Other options would be to locate them by ID, XPATH, TAG_NAME, CLASS_NAME, CSS_SELECTOR , etc (see table below). You can find more information here.
    • Next, it sends the query into the box element and clicks the search button.
    • If either the box or button are not located during the time established in the wait function (here, 5 seconds), the TimeoutException  is raised.
  • the next statement is a conditional that is true only when the script is run directly. This prevents the next statements to run when this file is imported.
    • it initializes the driver and calls the lookup function to look for “Selenium”.
    • it waits for 5 seconds to see the results and quits the driver

Finally, run your code with:

$ python selenium_script.py

Did it work? If you got an ElementNotVisibleException , keep reading!

How to catch an ElementNotVisibleExcpetion

Google search has recently changed so that initially, Google shows this page:

Google-Search

and when you start writing your query, the search button moves into the upper part of the screen.

Query-Google-Search

Well, actually it doesn’t move. The old button becomes invisible and the new one visible (and thus the exception when you click the old one: it’s not visible to click!).

We can update the lookup function in our code so that it catches this exception:

from selenium.common.exceptions import ElementNotVisibleException

def lookup(driver, query):
    driver.get("http://www.google.com")
    try:
        box = driver.wait.until(EC.presence_of_element_located(
            (By.NAME, "q")))
        button = driver.wait.until(EC.element_to_be_clickable(
            (By.NAME, "btnK")))
        box.send_keys(query)
        try:
            button.click()
        except ElementNotVisibleException:
            button = driver.wait.until(EC.visibility_of_element_located(
                (By.NAME, "btnG")))
            button.click()
    except TimeoutException:
        print("Box or Button not found in google.com")
  • the element that raised the exception, button.click() is inside a try statement.
  • if the exception is raised, we look for the second button, using visibility_of_element_located to make sure the element is visible, and then click this button.
  • if at any time, some element is not found within the 5 second period, the TimeoutException  is raised and caught by the two end lines of code.
  • Note that the initial button name is “btnK” and the new one is “btnG”.

Method list in Selenium

To sum up, I’ve created a table with the main methods used here.

Note: it’s not a python file — don’t try to run/import it 🙂

# INITIALIZE DRIVER
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()
driver.wait = WebDriverWait(driver, 5)


# WAIT FOR ELEMENTS
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

element = driver.wait.until(
    EC.presence_of_element_located(
    EC.element_to_be_clickable(
    EC.visibility_of_element_located(
        (By.NAME, "name")
        (By.ID, "id")
        (By.LINK_TEXT, "link text")
        (By.PARTIAL_LINK_TEXT, "partial link text")
        (By.TAG_NAME, "tag name")
        (By.CLASS_NAME, "class name")
        (By.CSS_SELECTOR, "css selector")
        (By.XPATH, "xpath")
    )
)


# CATCH EXCEPTIONS
from selenium.common.exceptions import
    TimeoutException
    ElementNotVisibleException

That’s all! Hope it was useful! 🙂

Don’t forget to share it with your friends!

Leave a Reply Cancel reply

You must be logged in to post a comment.

Categories

  • Personal Growth and Development
  • Mindful Parenting and Family Life
  • Productivity and Time Management
  • Mindfulness and Wellness
  • Values and Life Lessons
  • Posts en català
  • Other things to learn

Recent Posts

  • Overcoming Regrets: Finding the Strength to Move Forward
  • Thinking Outside the Box: Creative Problem-Solving with Critical Thinking
  • Assertiveness: A Crucial Skill for Children’s Personal Growth
  • Els nens no son responsables de les emocions dels altres
  • Children are not responsible for other people’s emotions

RSS

  • Entries RSS
Follow @marina_mele
  • Cookie Policy
  • Privacy Policy
©2023 Marina Mele's site | Built using WordPress and Responsive Blogily theme by Superb
This website uses cookies to improve your experience. If you keep navigating through this website, we'll assume you're ok with this, but you can opt-out if you wish.Accept Read More
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT