Scraping web pages is a well documented process. There are plenty of guides on how to pull information using plugins like Python’s Beautiful Soup or browser extensions like Kimono. Many web applications even provide public APIs for gathering information, such as Facebook’s Graph API.
Yet, there is a growing set of popular mobile apps that do not have a public API. Apps like Yik Yak, Tinder, and others contain a wealth of information about the communities around us, but there are no common tools for easily collecting data from these platforms.
Information about these mobile communities has become increasingly relevant in understanding and reporting the news. Yik Yak, for example, recently played a role in highlighting the oppressive social tones at University of Missouri.
So how can we scrape from mobile apps? After being inspired by this blog post about mining Yik Yaks from university areas, I decided to try creating my own scraper for Whatsgoodly. I’ll share my process.
For web scraping, the general strategy is to pull information that is within the HTML contained on a given web page. For mobile scraping, we take a different approach. Since there are no HTML files to crawl through, the strategy is to monitor the endpoints that the app loads data from so that we can use the same endpoints in our custom scraper.
More specifically, the steps I took were:
- Setup a Genymotion virtual device and install Whatsgoodly
- Monitor the app's network activity with a Charles proxy
- Discover the relevant endpoints and write a scraping script
Installing the application on a Genymotion Simulator
For this project, I used the latest version of Genymotion and added a virtual device running Android 5.1.0. Genymotion is helpful because it allows you to run virtual Android devices from your computer. Here’s a guide to help you get started. After you’ve added a device, start it!
The next step is to download the application you want to scrape. Generally, this is as easy as simply finding the Android Application Package (.apk file) for the application from one of many websites such as APKPure or AndroidAPKsFree and dragging it onto your device’s screen.
While trying to install Whatsgoodly using this method, I ran into some problems with getting the app to run. So instead, I installed Google Play by following anp8850’s answer on this Stack Overflow post. When following these instructions, I found that I did not need to run any of the terminal commands. Instead, I just restarted the virtual device after loading files. Once Google Play was on the device, I simply logged in and downloaded Whatsgoodly.
Monitoring Network Activity with Charles
The next step is to learn how the application loads data by tracking the HTTP/HTTPS requests it sends. To do this, I used a free trial of Charles — a web debugging proxy application.
After opening Charles, you should be able to see activity coming from the pages that are open in your web browser, but you will not be able to see any traffic from your Genymotion virtual device. This is because Genymotion’s virtual network adapter operates independently from your computer’s internet protocol stack. We can remedy this by using a Charles proxy to intercept the traffic from the virtual device. I followed Scrums of Anarchy’s first few instructions on how to connect the device to the Charles proxy. While following the instructions, remember to use the computer’s IP address for the “Proxy Hostname” field.
If everything works, you should be seeing something similar to the example below.
We’re almost there, but the issue is that we’re not seeing much information about the requests. Notice that we only see CONNECT methods, and that there is no information in Path field. This is because the app is using HTTPS request, which Charles is not allowed to collect details about. To allow Charles to see details about HTTPS requests, simply open a browser on the virtual device and use it to navigate to the Charles SSL download page. This should automatically initiate the installation of a Charles Root Certificate onto your virtual device. After it’s installed, restart Genymotion and Charles. Charles should now be able to capture information about HTTPS requests.
Finding the the relevant endpoints and writing a scraper
Now that we can see information about all of the requests coming from our app through Charles, all we need to do is track down the useful ones.
The first step here is to go through the actions you want to capture on the virtual device. Doing things like signing in, refreshing a page, or posting a comment while Charles is recording will help you to find out what endpoints handle what actions in the app.
Charles’ Path field will be helpful once you’ve recorded some actions to analyze, as well as the Request and Response tabs on the bottom half of the screen. We just need to look the recorded requests, and then create custom versions of these requests programmatically from our scraper program.
I chose to write my program for scraping Whatsgoodly in Python, and used the Requests library to create structured GET requests to get the polls at a specified location. The tricky part here is to understand what HTTP headers to use for the requests. Using Charles’ Request tab, you can see the headers that were sent with each call so that you can use the same header structure in your program. This is a game of trial and error, but one thing that can help here is testing out your requests using a REST client like DHC!
That’s it! You can view the progress I have made as an example implementation at the Whatsgoodly Scraper repository. Please reach out if you have any comments or questions about the process!