Web Scraping Football Data with Python (Part 3):
Accessing Shot Data from FotMob the Right Way
If you’re reading this, chances are you already realized something important: free, high-quality football data is getting harder to find. And yet, you’re still here — which means you’re willing to learn how to get it yourself.
Before we go any further, let me be very clear about one thing 👇
If you want to see how these data turn into real insights — shot maps, xG profiles, passing tendencies — you can already explore all of that in the Football Hacking web app, completely free:
👉 Access the Football Hacking web app here
Now let’s get to work.
Why This Series Matters More Than Ever
At the moment this article is being written, Opta has officially ended its partnership with FBRef.com. As a result, advanced football data is no longer available on FBRef.
That changes everything.
For years, FBRef was the go-to source for analysts, students, content creators, and football fans who wanted high-level data without paying expensive subscriptions. That door is now closed.
But here’s the good news:
FotMob is still there.
And with the right approach, you can still access advanced football data for free.
This is exactly why web scraping is no longer optional — it’s a core skill for anyone who wants independence when working with football data. And I’m here to help you build that skill, step by step.
🙏 Thank you for trusting my work and following this series.
If you’re already a subscriber, your support makes this possible.
If you’re not yet a subscriber, this is the perfect time to join and keep learning with us.
A Quick Recap: Where We Left Off
In the previous article — which you can read here:
—we learned how to:
Connect to FotMob’s internal API
Retrieve league and match-level data
Access the structure that FotMob uses to organize match information
That foundation is essential. Today, we’re building on top of it.
But before we move forward, we need to deal with a very common web scraping problem.
When Websites Change (And They Always Do)
During the production of this article, something unexpected happened.
The page where the x-mas value (used in the request headers) was previously located is no longer available.
At first glance, that might sound alarming — but it really isn’t.
After inspecting the network requests more carefully, I noticed something important:
👉 The x-mas header is no longer required at this moment.
This leads us to a simple but robust solution.



