{"id":32246,"date":"2022-09-07T12:56:22","date_gmt":"2022-09-07T10:56:22","guid":{"rendered":"https:\/\/www.wbscodingschool.com\/?p=32246"},"modified":"2025-05-12T15:33:52","modified_gmt":"2025-05-12T15:33:52","slug":"web-scraping-with-python-for-beginners-how-to-get-started","status":"publish","type":"post","link":"https:\/\/www.wbscodingschool.com\/blog\/web-scraping-with-python-for-beginners-how-to-get-started\/","title":{"rendered":"Web Scraping With Python For Beginners: How To Get Started"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Web scraping is the process of using programming tools to extract data from a website. It is also a skill that has exploded in relevance in the past couple of decades, as the amount of information amassed on the internet has offered more and more information to businesses, researchers, marketers, and journalists, among many others.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this article we will look at some of the basic functions offered by Python for web scraping, as well as how to retrieve data via APIs. This is not an exhaustive exploration of the topic (such a thing would take much more than just one article!), only a gentle introduction that should allow you, as a beginner, to get started with getting data from the internet in practice.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before starting, please be mindful of what data you scrape, from where, and what you wish to do with it. Some websites contain private data, others are subject to copyright. If you wish to retrieve data online beyond the step-by-step examples in this article, please <a href=\"https:\/\/scrape.do\/blog\/how-to-check-if-a-website-allows-scraping\" target=\"_blank\" rel=\"noopener\">check if you have permission<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While this article is for the beginner, we will assume a minimum level of literacy with Python. You should already know what variables, loops and functions are, for example.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The contents of this article will be organised as follows:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>CONTENTS<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#p1\" data-type=\"internal\" data-id=\"#p1\">First Things First: What Libraries Will You Need?<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#p2\">Understanding The Code Of A Web Page<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#p3\">Getting Started With Requests<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#p4\">Put Beautiful Soup To Use<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#p5\">Web Scraping With APIs<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#p6\">Retrieving Dynamic Data About Flights<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em><a href=\"#pf\">Conclusion: The Next Steps<\/a><\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With no further ado then, let\u2019s get you scraping the web!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"p1\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>First Things First: What Libraries Will You Need?<\/em><\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"754\" src=\"https:\/\/www.wbscodingschool.com\/files\/2.-AdobeStock-by-Ryan_340078556-1024x754.jpeg\" alt=\"Web scraping for with Python for beginners Books on Shelves in Library or Study with Classic Dark Wood\" class=\"wp-image-32273\"><figcaption class=\"wp-element-caption\">Adobe Stock \/ Ryan<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As is often the case with a general-use language like Python, performing specialised tasks will require libraries designed specifically for those purposes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When it comes to scraping data from the internet, there are two different libraries that you should familiarise yourself with. The first is <strong>Requests<\/strong>, while the second is<strong> Beautiful Soup<\/strong>. We will introduce you to both in greater detail over the course of the article.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will also be making a marginal use of <strong>Pandas<\/strong>, the popular Python library for analysing and manipulating data. You will need Pandas again if you intend to plot, visualize or manipulate the data you scrape, but for the purposes of this particular guide, we will only be using one of its methods.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"p2\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Understanding The Code Of A Web Page<\/em><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For those who have been learning Python (and programming in general) for purposes other than web development, let\u2019s start from the absolute basics.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The majority of webpages is composed of code written in three languages: HTML, CSS, and JavaScript. Right now we are interested in getting information primarily from HTML.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The good news is that the HTML code for any given website is <strong>incredibly easy to find.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Simply open a webpage, right click with your mouse anywhere within it, and you will open a scroll down menu with a number of options. At the bottom of that menu you will find an option called <em>Inspect<\/em>. Click on it, and a whole new section will open (either on the right hand side or the bottom of your browser), showing you the code that composes the website.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/1.-inspect.webp\" alt=\"\" class=\"wp-image-32247\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>This newly-opened \u2018section\u2019 is called is called the Developer Tools, or DevTools<\/strong>. It is an incredibly powerful resource to explore, analyse and even edit the webpage you are on. Today we will look at only one of the many things that we can do with it: retrieving its HTML code and the information it contains.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/2.-devtools.webp\" alt=\"\" class=\"wp-image-32250\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The HTML code of a website is the long script that you will see in the DevTools you just opened (right beneath the title \u2018elements\u2019)<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong><em>Pro tip: <\/em><\/strong><em>If you want to see the code that generates a <strong>particular<\/strong> part of the website (for example the specific paragraph of text that you are reading, or an image, or a button), simply highlight that part, right click on it, and click inspect. The section will open at the pertinent line of code, highlighting it for you to see!<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/inspecting-an-element-3.webp\" alt=\"\" class=\"wp-image-32344\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This code that you have revealed contains literally all of the information that is in the page you are visiting. In its raw form, however, it is difficult to read, and even more difficult to use.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is where Requests comes to our aid.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"p3\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Getting Started With Requests<\/em><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It makes sense to start with Requests, as this library involves some basic concepts which we will use again later on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Requests is one of a number of libraries (alongside httplib, urllib, httplib2, and treq) that can be used to do exactly what this guide is about:<strong> retrieve information from web pages<\/strong>, or what in the business is known as<strong> web scraping.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">How is this done? Open your console and let\u2019s do this together!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, of course, we import the Requests library.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>import requests<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then we use the \u2018get\u2019 method from that same library on the URL of a website to get the contents of that website, that is to say, its HTML code. We will store those contents in an object called <em>response<\/em>, as this is, after all, the response by the website to our request.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>response = requests.get('https:\/\/www.imdb.com\/title\/tt0034583\/fullcredits\/?ref_=tt_ql_cl')<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The response object isn\u2019t a simple thing.<\/strong> It contains the retrieved data, as well as a variety of attributes and methods to retrieve it. This means that whenever we want to do anything with it, we can\u2019t just treat it like any old variable \u2013 rather, <strong>we need to specify which part of it we want to work with<\/strong>. For example:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/print.webp\" alt=\"\" class=\"wp-image-32301\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can get the same results by writing <em>print(response.content)<\/em> Just bear in mind that we can\u2019t simply write <em>print(response)<\/em>. This is because the response object in its entirety is more than just readable text, and would therefore return an error if you tried to print it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You should also know that Request methods can also be written in this syntax:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>\u00a0<\/em><code>requests.request(method, url, **kwargs).<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This means that our line <em>response = requests.get(&#8218;https:\/\/www.imdb.com\/title\/tt0034583\/fullcredits\/?ref_=tt_ql_cl)<\/em> could also have been written like this:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>response = requests.request('get', 'https:\/\/www.imdb.com\/title\/tt0034583\/fullcredits\/?ref_=tt_ql_cl')<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we have converted all of the contents of a website into a response object, we can do all sorts of things with it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For a complete list of all the methods that you can use with Requests, <a href=\"https:\/\/requests.readthedocs.io\/en\/latest\/\" target=\"_blank\" rel=\"noopener\">check out the official documentation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"p4\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Put Beautiful Soup To Use<\/em><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once you have an HTML response object on your Python console, it\u2019s time to work with it. The library Beautiful Soup exists to let you pull data out of HTML and XML files, and is perfectly suitable for our purposes. So how do we use it?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once again, let\u2019s do this step by step. First of all, import the library Beautiful Soup into your Python script.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>from bs4 import BeautifulSoup<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will then use the method html.parser, which is Python\u2019s in-built parser, to turn our response object into something that Python can work with. We will use it on the HTML code we have scraped and put the result into a new variable, which here we will call <em>soup<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>soup = BeautifulSoup(response.text, 'html.parser')<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">What can we do with this \u2018soup\u2019? Let\u2019s have a look.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">HTML code is composed of <em>tags<\/em>, which are pairs of letters or words that wrap up each item of content on a web page, and which are contained by the symbols &lt;&gt; and &lt;\/&gt;. Thus, a paragraph of text on a webpage will be indicated by the letter <em>p<\/em> and written like so:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>&lt;p&gt;This is a paragraph.&lt;\/p&gt;<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With this in mind, we can explore the contents of a web page simply by asking Python to show us its appropriate HTML tags:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/soup1.webp\" alt=\"\" class=\"wp-image-32308\"><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/soup2.webp\" alt=\"\" class=\"wp-image-32311\"><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/soup3-1.webp\" alt=\"\" class=\"wp-image-32314\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can explore tags in greater depth by concatenating them in the same command.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/soup4.webp\" alt=\"\" class=\"wp-image-32317\"><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/soup5.webp\" alt=\"\" class=\"wp-image-32320\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A more practical way to explore this code is to use methods built specifically for that purpose. For example:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>soup.find(\"p\")<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will only return the first element of its type that it finds, so in this case the first paragraph.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>soup.find_all(\"p\")<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will return <em>all<\/em> the elements of this type, so in this case all paragraphs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another option instead of .find_all() is to use .select(), which will locate all the elements of a CSS class, and \u2013 importantly \u2013 return them <em>as a list<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that .select() requires an uncommon syntax to be used. It lets you conveniently find tags within other tags, but you must call them both within the same inverted commas (as though they were both parts of a string), and surprisingly, you don\u2019t have to separate them with a comma. Meanwhile, different attributes that are part of the same tag (for example, a CSS class) are separated by full stops!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This means that for an HTML code that looks like this&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;div class=\"parent\"&gt;<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0 &lt;h3 itemprop=\"name\"&gt;<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>&lt;a href=\"<a href=\"https:\/\/www.imdb.com\/title\/tt0034583\/?ref_=ttfc_fc_tt\" target=\"_blank\" rel=\"noopener\">\/title\/tt0034583\/?ref_=ttfc_fc_tt<\/a>\"<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>itemprop='url'&gt;Casablanca&lt;\/a&gt;<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u2026the way one asks Python to find all the &lt;a&gt; beneath the &lt;div&gt; tags that contain a class called \u201cparent\u201d is this:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>soup.select(\"div.parent a\")<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">See what\u2019s happening there? \u2018Parent\u2019 is a <em>class<\/em> within the tag called \u2018div\u2019, so we call that div.parent. At the same time, <em>a<\/em> is the tag within the higher tag <em>div<\/em>, so we divide that from \u2018title.movies\u2019 with just a blank space, and we also wrap up both the <em>div<\/em> and the <em>a<\/em> within the same inverted commas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This can be confusing for the beginner at first, but you\u2019ll get used to it with practice!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A particularly common and useful method is get_text,\u00a0 which \u2013 as the name suggests \u2013 will return the parts of a webpage that are actually meant to be read.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/soup6.webp\" alt=\"\" class=\"wp-image-32324\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You can combine all of these methods with regular Python loops to explore and manipulate the HTML code app your leisure.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>for\u00a0p\u00a0in\u00a0soup:<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(soup.p.get_text())\u00a0<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It then becomes relatively simple to write Python functions that let you repeat particular tasks on different pages of the same website, as long as those pages are structurally similar. A function that lets me print the names of all the actors in the IMDB cast page of <em>Casablanca<\/em> should do the same for the cast page of <em>The Godfather<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"p5\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Web Scraping With APIs<\/em><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We\u2019ve looked at some of the basic methods to take data from the internet and put it into your Python console so you can work with it. Let\u2019s now look at something just a little more complex.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Web scraping is generally easier the more static the data you are working with is. A function that takes the name of a city and returns its latitude and longitude based on its Wikipedia page is relatively easy to build, for example, because neither the coordinates nor the website displaying them will change. To whit, you just get the function to create a soup based on its url as an f_string&#8230;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>city = \"Berlin\"<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>html = requests.get(f\"https:\/\/en.wikipedia.org\/wiki\/{city}\")<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>soup = BeautifulSoup(html.text, 'html.parser')<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8230;then you identify which tags within the HTML code contain the coordinates, extract them with .find() or .select(), and get the function to return those. In this case the relevant tag is called <em>span<\/em>, and its CSS classes are <em>latitude<\/em> and <em>longitude<\/em> respectively.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"706\" src=\"https:\/\/www.wbscodingschool.com\/files\/apis-1-1024x706.png\" alt=\"\" class=\"wp-image-32256\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/apis-2.webp\" alt=\"\" class=\"wp-image-32259\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>latitude\u00a0=\u00a0soup.select(\"span.latitude\")<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>longitude\u00a0=\u00a0soup.select(\"span.longitude\")<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>print(f\"For\u00a0{city},\u00a0the\u00a0longitude\u00a0is\u00a0\"\u00a0+\u00a0longitude[0].get_text()<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>+\u00a0\"\u00a0and\u00a0the\u00a0latitude\u00a0is\u00a0\"\u00a0+\u00a0latitude[0].get_text())<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Done and done!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, things get a lot trickier when you want to use Python to handle data that is constantly changing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suppose, for instance, that you wanted to create a function that checks the results for matches played in a particular football league. Now you are dealing with results that are changing all the time, and the web pages showing these results will change accordingly. How can we do this?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Skilled data scientists are able to write complex, flexible code that can investigate dynamic queries using a combination of different web resources. But beginners won\u2019t have to go that far.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the most popular queries related to dynamic data \u2013 including things like the results of football games \u2013 there already exist online resources that do the work of storing and updating that data regularly. These resources aren\u2019t always fully-fledged websites \u2013 they may be something as simple as APIs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An API, or Application Programming Interface, is simply the code that websites use to request data from each other. APIs are made up of <em>routes<\/em>, and actually consist of pretty simple code. You can see an example of an API simply by looking at the URL of any given website \u2013 that URL is, precisely, the API that tells your browser where to go!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For example, here is the API for a YouTube video:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>https:\/\/www.youtube.com\/watch?v=dQw4w9WgXcQ<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And here\u2019s what this is doing:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>https:\/ \u2013 This tells the program what transmission protocol to use, in this case <a href=\"https:\/\/www.cloudflare.com\/en-gb\/learning\/ssl\/what-is-https\/\" target=\"_blank\" rel=\"noopener\">HTTPS<\/a>.<\/li>\n\n\n\n<li>\/www.youtube.com \u2013 This tells the program which website to look in.<\/li>\n\n\n\n<li>\/watch?v=dQw4w9WgXcQ \u2013 This requests the video whose ID is <em>dQw4w9WgXcQ<\/em>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">When learning web-scraping, you will want to find out how to work with APIs and where to find them. <strong>One extremely useful hub for this purpose is <\/strong><a href=\"https:\/\/docs.rapidapi.com\/docs\/what-is-rapidapi\" target=\"_blank\" rel=\"noopener\"><strong>RapidAPI<\/strong><\/a><strong>, which collects the APIs of websites storing dynamically updated data.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">RapidAPI provides a wealth of API keys which respond directly to your requests \u2013 in our example above, their API key would return the updated results of football matches, which you can then explore and manipulate as code. Some of the more <a href=\"https:\/\/rapidapi.com\/collection\/popular-apis\" target=\"_blank\" rel=\"noopener\">popular resources on RapidAPI<\/a> provide information about things like the weather, transport, and finance, which of course are changing all the time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s look at how to take one of their API keys and turn it into information that Python can use.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"p6\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Retrieving Dynamic Data About Flights<\/em><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this example, we will create a simple dataframe out of an API key which will allow us to query information about airports world-wide.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Firstly, you will have to create an account on RapidAPI. As long as you\u2019re just practising, choose the free subscription. Be aware that this will limit your number of API requests to 200 per month.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, navigate to <a href=\"https:\/\/rapidapi.com\/collection\/flight-data-apis\" target=\"_blank\" rel=\"noopener\">their page listing the APIs for flight data<\/a>. A variety of options is available, but we will select <a href=\"https:\/\/aerodatabox.com\/\" target=\"_blank\" rel=\"noopener\">AeroDataBox<\/a> for our example.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the AeroDataBox window, on the left, you will get the option to look for data about flights, airports, and aircraft, among others. Let\u2019s select <em>Airport APIs<\/em>, then from the scroll-down options, <em>Search airports by free text<\/em>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/rapidapi1.webp\" alt=\"\" class=\"wp-image-32262\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Then, on the right, select Python &gt; requests from the drop down options to get a request code that is already formatted for the language you are using.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/rapidapi2.webp\" alt=\"\" class=\"wp-image-32265\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You should get something like this (obviously my API key here has been blacked out!), and you can just copy the whole thing directly into your console:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>import requests<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>url = \"https:\/\/aerodatabox.p.rapidapi.com\/airports\/search\/term\"<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>querystring = {\"q\":\"Berlin\",\"limit\":\"10\"}<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>headers = {<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"X-RapidAPI-Key\": \"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\",<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \"X-RapidAPI-Host\": \"aerodatabox.p.rapidapi.com\"<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>}<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>response = requests.request(\"GET\", url, headers=headers, params=querystring)<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>print(response.text)<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">An important note: <strong>the response objects that you get from these APIs will not come in an HTML format, like the examples we have used above<\/strong>. Instead, they will come in <a href=\"https:\/\/www.youtube.com\/watch?v=JuFdz8f-cT4\" target=\"_blank\" rel=\"noopener\">JSON format, which is made for storing and transforming data<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this reason, if you want to give your data a look with your own eyes, you will want to use the Request method <strong>.json()<\/strong>, which will make that data readable for us. In the example above, just add response.json() at the bottom of your code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we have the data, let\u2019s call the Pandas library to our aid and perform a little act of magic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>import Pandas as pd<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We will create an entire dataframe by adding this little pandas method at the bottom of the code given to us by RapidAPI:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>pd.json_normalize(response.json()['items'])<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Marvel at the beautiful simplicity of this! The json_normalize() method from Pandas turns JSON contents (in this case our response objects) into a dataframe for whichever tag you choose to specify. In case you\u2019re wondering why we chose \u2018items\u2019, just take a look at the contents of response.json().<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/www.wbscodingschool.com\/wp-content\/uploads\/2022\/09\/response-pic.webp\" alt=\"\" class=\"wp-image-32304\"><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, the response object contains three dictionaries, contained within a list, all wrapped up in another dictionary that has just one key \u2013 <em>items<\/em>. When using .json_normalize(), we therefore need to specify that we want to create our columns out of the stuff that is <em>inside<\/em> of \u2018items\u2019.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In any case, now you have a table which lets you query information about airports worldwide. Typing \u2018Berlin\u2019 in the querystring, for example, gives you a table with all the airports in Berlin \u2013 try amending that to \u2018London\u2019 to see some funny results, as the program brings in airports in USA locations that are also called \u2018London\u2019! You can also search for airports by their names, or by their ICAO and IATA codes. Moreover, this new table is flexible and easy to amend.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A final note \u2013 you may notice that if the querystring is amended to search by country code or location coordinates, it doesn\u2019t work. For the country code, this has to do with the fact that countries are not directly linked to individual airports in this API. For location coordinates, look again at response.json(). You\u2019ll notice that the key \u2018location\u2019 contains a dictionary of its own, in which latitude and longitude are kept separate. The way to access them therefore requires you to specify first the greater dictionary key, then the position in the list, and finally the key of the internal dictionary:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>response.json()[\"items\"][0][\"location\"]<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In sum, you have now retrieved data from an API and put it into your console for your use and your leisure. Other APIs, particularly those that contain time-sensitive data, will require some more sophisticated tinkering to return dynamically updated results \u2013 for instance the use of the library <strong>datetime<\/strong> to let the program automatically update the desired time of the operation. Discussing these case studies would take us into the next level of complexity, and therefore beyond the scope of this basic introduction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"pf\"> <\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><em>Conclusion: The Next Steps<\/em><\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.wbscodingschool.com\/files\/3.-AdobeStock-by-Bahobank_414089417-1024x576.jpeg\" alt=\"Web scraping for with Python for beginners The ladder of success that sparkles. 3D Render\" class=\"wp-image-32276\"><figcaption class=\"wp-element-caption\">Adobe Stock \/ Bahobank<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we have introduced you to the basics of using <strong>Beautiful Soup<\/strong> and <strong>Requests<\/strong>, and one particular use of <strong>Pandas<\/strong> that can make your life easier. As you get busy scraping data by yourself, you will probably need to use all of these libraries more extensively.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To make that easier for you, we will end this article with a few resources to help guide you on your next steps. Here is <a href=\"http:\/\/omz-software.com\/pythonista\/docs\/ios\/beautifulsoup_guide.html\" target=\"_blank\" rel=\"noopener\">a detailed and beginner-friendly guide for using Beautiful Soup<\/a>, and here is a similar <a href=\"https:\/\/realpython.com\/python-requests\/\" target=\"_blank\" rel=\"noopener\">guide for Requests<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You may also want to go deeper with Rapid API, in which case here is a <a href=\"https:\/\/docs.rapidapi.com\/\" target=\"_blank\" rel=\"noopener\">link to their official documentation<\/a>. They also have <a href=\"https:\/\/rapidapi.com\/guides\" target=\"_blank\" rel=\"noopener\">a page dedicated specifically to guides<\/a>, which is fun if you want to explore what can be done with their website (although many of the examples there won\u2019t be so beginner-friendly).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, if you truly are committed to learning Python for Data Science in depth, you could always <a href=\"https:\/\/www.wbscodingschool.com\/data-science-bootcamp\/\">consider our bootcamp<\/a>, which covers \u2013 among many other things \u2013 how to set up an automated data pipeline on the cloud, so that your programs can collect data all by themselves!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This was a beginner guide, but if you keep learning the way you did by reading this article, you will not be a beginner for long. Now go forth and conquer the internet!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A guide on how to get data from websites and APIs using Python<\/p>\n","protected":false},"author":17,"featured_media":32270,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[42],"tags":[],"class_list":["post-32246","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-coding"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/posts\/32246","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/comments?post=32246"}],"version-history":[{"count":1,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/posts\/32246\/revisions"}],"predecessor-version":[{"id":62558,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/posts\/32246\/revisions\/62558"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/media\/32270"}],"wp:attachment":[{"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/media?parent=32246"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/categories?post=32246"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wbscodingschool.com\/de\/wp-json\/wp\/v2\/tags?post=32246"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}