<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Valentina Skakun on Medium]]></title>
        <description><![CDATA[Stories by Valentina Skakun on Medium]]></description>
        <link>https://medium.com/@valka465?source=rss-4f9f04d88447------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*1cpo5fwQ_HOtggtQskxyzQ.jpeg</url>
            <title>Stories by Valentina Skakun on Medium</title>
            <link>https://medium.com/@valka465?source=rss-4f9f04d88447------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 06 Aug 2026 01:44:55 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@valka465/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Python Web Scraping for Beginners: A Step-by-Step Guide]]></title>
            <link>https://valka465.medium.com/python-web-scraping-for-beginners-a-step-by-step-guide-d0cb9e1e3723?source=rss-4f9f04d88447------2</link>
            <guid isPermaLink="false">https://medium.com/p/d0cb9e1e3723</guid>
            <category><![CDATA[scraping]]></category>
            <category><![CDATA[guides-and-tutorials]]></category>
            <category><![CDATA[scraping-with-python]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[beginners-guide]]></category>
            <dc:creator><![CDATA[Valentina Skakun]]></dc:creator>
            <pubDate>Mon, 24 Feb 2025 11:14:06 GMT</pubDate>
            <atom:updated>2025-02-24T11:14:06.707Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UKkemjsdHlqRykr8xV8UvQ.png" /></figure><p>Alright, I won’t waste time explaining why you need this guide. Instead, I’ll keep it simple and show you the easiest ways to get the data you need from any website using a Python script.</p><p>There are basically four main approaches:</p><ol><li><strong>Basic request &amp; parsing.</strong> You write a script using a library like requests, urllib, or http.client to fetch the page, then parse the result using tools like BeautifulSoup or lxml. The downside? This won’t work on sites that rely heavily on JavaScript.</li><li><strong>Simulating a real user.</strong> If the first method fails, you’ll need something more advanced — like browser automation. Libraries such as Selenium, Pyppeteer, or Playwright let you control a real browser, so you can interact with JavaScript-heavy pages.</li><li><strong>Using a dedicated scraping framework.</strong> This is where Scrapy comes in. Technically, it could fit into one of the first two categories, but since it’s a self-sufficient framework designed specifically for web scraping, it deserves its own mention.</li><li><strong>The easiest option — using an API.</strong> Some services scrape the data for you, so all you need to do is send a request and process the response.</li></ol><p>Before we jump into examples, just a heads-up: if you’re using one of the first three methods, you’ll have to deal with captchas, proxies, and other stuff websites use to block scrapers. If that sounds like too much trouble, just go with an API that does the work for you. My personal recommendation? <strong>HasData</strong>. But yeah, you probably guessed that.</p><p>Alright, enough intro. Let’s get to the actual guide.</p><p><strong>Requests &amp; BeautifulSoup</strong></p><p>The easiest way to start scraping something is with the Requests library and BeautifulSoup. It works well, but honestly, it’s only good for the simplest and most static websites, which are getting rarer these days. Still, it’s a great way to get your feet wet with scraping.</p><p>So, to make things easier, I uploaded a scraping script using Requests and BeautifulSoup on <a href="https://colab.research.google.com/drive/1yabcI6KpuV4tmfW2nU-3n6s2tQAa85va?usp=sharing">Google Colab</a>. This way, you don’t even need to install Python on your computer to run it.</p><p>But if you want to run it on your own machine, let’s dive in. Generally, both Requests and BeautifulSoup come pre-installed, but if you’re using virtual environments, you might need to install them yourself with this command:</p><pre>pip install requests beautifulsoup4</pre><p>After that, create a new file and import them into your script like this:</p><pre>import requests<br>from bs4 import BeautifulSoup</pre><p>Then, you’ll need to set the URL for the page you want to scrape:</p><pre>url = &quot;https://example.com&quot;</pre><p>Next, just go to that link and parse the data using CSS selectors:</p><pre>response = requests.get(url, headers=headers)<br><br>soup = BeautifulSoup(response.text, &quot;html.parser&quot;)<br>title = soup.find_all(&quot;h1&quot;)</pre><p>And that’s pretty much it! If you want a slightly more complex example, check out the <a href="https://colab.research.google.com/drive/1yabcI6KpuV4tmfW2nU-3n6s2tQAa85va?usp=sharing">Google Colab</a> notebook. I added headers (just make sure to change the <a href="https://hasdata.com/blog/user-agents-for-web-scraping">User Agents</a> to something current), and I also included a check to see if the request was successful. If it is, we gather all the links from the page; if not, we print out an error message.</p><p>Overall, it looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/952/1*BQ0T4f9PZ0YlnMASedAj8g.gif" /></figure><h4><strong>Example with Scrapy</strong></h4><p>Let’s talk about the Scrapy framework. To be honest, I’m not a huge fan, but it’s definitely worth mentioning because it’s a solid framework for scraping. First things first, let’s install Scrapy:</p><pre>pip install scrapy</pre><p>Next, we’ll create a new project:</p><pre>scrapy startproject scrapy_example<br>cd scrapy_example<br>scrapy genspider titles_scrapy_example example.com</pre><p>It should look something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MEHoQTfrJ31KQUGGwr6aTQ.gif" /></figure><p>Then, open the file of the spider you just created (Scrapy calls them spiders) and edit it like this:</p><pre>def parse(self, response):<br>    titles = response.css(&quot;h1&quot;).extract()<br>    yield {&#39;titles&#39;: titles}</pre><p>Right here:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U043Xyi-erq0OkZJCWQAvg.gif" /></figure><p>Or, if you prefer using XPath, you can do it this way:</p><pre>def parse(self, response):<br>    titles = response.xpath(&quot;//h1/text()&quot;).extract()<br>    yield {&#39;titles&#39;: titles}</pre><p>Just a quick note:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fO9v3wdKUJXd7yt3AWbEHw.gif" /></figure><p>You can have multiple spiders in your project, not just one. To run your entire project with all its spiders, use this command:</p><pre>scrapy crawl titles_scrapy_example</pre><p>Just make sure to replace it with your project name. It looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Yh6lGXNGWUytdOamsSUVjQ.gif" /></figure><h4>A Bit About Headless Browsers</h4><p>So, let’s talk about my favorite topic — headless browsers. I’ll start with the less popular ones and work my way to the one I’ll use for an example. First up is Playwright. It’s not super famous, but I’ve heard that testers really know their stuff when it comes to it 😉</p><p>Then there’s Pyppeteer, which is basically a wrapper for the popular NodeJS tool, Puppeteer. It’s not super popular in Python, but if you want to make your script asynchronous, this is where you’d want to go.</p><p>And lastly, the big one that you probably guessed I’d talk about — Selenium. There are times when even Selenium struggles, like when you’re trying to scrape data from Ahrefs. But no worries, there’s SeleniumBase with its cool UC mode that does a great job of hiding the fact that it’s a bot.</p><p>But today, that’s not really what we’re focusing on. If you’re interested in that, just let me know, and I’ll definitely write about it later. For now, let’s stick with a simple example of launching a web driver, navigating to a page, and scraping some data.</p><p>First, as always, you need to install it:</p><pre>pip install selenium</pre><p>Then, import Selenium and all the necessary modules:</p><pre>from selenium import webdriver<br>from selenium.webdriver.common.by import By<br>from selenium.webdriver.chrome.options import Options</pre><p>Now, let’s create a driver object, go to a webpage, and get some data:</p><pre>url = &quot;https://example.com&quot;<br><br>chrome_options = Options() <br>driver = webdriver.Chrome(options=chrome_options)<br><br>driver.get(url)<br><br>paragraphs = driver.find_elements(By.CSS_SELECTOR, &#39;p&#39;)<br>for paragraph in paragraphs:<br>    print(paragraph.text)</pre><p>And don’t forget to close the web driver at the end:</p><pre>driver.quit()</pre><p>So, that’s how it looks:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0bR6aRP4wy6qVbvOoBubdg.gif" /></figure><h4>The Tastiest Part — A Web Scraping API Example</h4><p>If you’re as lazy as I am, then the easiest way is to use a ready-made API that fetches all the data for you and returns it in a nice, structured way. As you’ve probably guessed, the example here will be using <a href="http://hasdata.com">HasData’s API</a>.</p><p>Sure, we could scrape some random website ourselves, but honestly, that’s not very exciting. If you’re curious about scraping a specific site, feel free to drop a comment or message me on LinkedIn — I might write about it.</p><p>Anyway, back to the point. I want to show how to use an API with an example of the <a href="https://hasdata.com/apis/google-serp-api">SERP API</a>. This feels especially relevant after Google’s update on January 16.</p><p>I’ve also uploaded a working script to <a href="https://colab.research.google.com/drive/1UFP1BcqgFoK1MiK2cA3coxL6qxznm4ig?usp=sharing">Google Colaboratory</a>, so you can check it out there right away.</p><p>We only need the requests library and a HasData API key. First, we import the library and set the endpoint:</p><pre>import requests<br><br>base_url = &quot;https://api.hasdata.com/scrape/google/serp&quot;</pre><p>Then, we define the parameters, including the HasData API key:</p><pre>query = &quot;Coffee&quot;<br>location = &quot;Austin,Texas,United+States&quot;<br>device_type = &quot;desktop&quot;<br>api_key = &quot;YOUR-API-KEY&quot;</pre><p>Next, we set the headers, make the request, and get the data:</p><pre>url = f&quot;{base_url}?q={query}&amp;location={location}&amp;deviceType={device_type}&quot;<br>headers = {<br>    &#39;Content-Type&#39;: &#39;application/json&#39;,<br>    &#39;x-api-key&#39;: api_key<br>}<br>response = requests.get(url, headers=headers)<br><br>data = response.json()</pre><p>Finally, we print the data:</p><pre>print(data)</pre><p>For convenience, I’ve uploaded a version in Colab Research that saves the data as well:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WMJUUeP6MIimFVEZA9Tcfw.gif" /></figure><h4>Wrapping Up</h4><p>If you want more details, examples, or explanations about these libraries, check out HasData — I’ve already written about how to <a href="https://hasdata.com/blog/web-scraping-with-python">get started with Python</a> and compared different <a href="https://hasdata.com/blog/best-python-libraries-for-web-scraping">web scraping libraries</a>.</p><p>Or just drop a comment about what you’d like to read next, and I’ll keep it in mind for my next article.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d0cb9e1e3723" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>