Last active
April 5, 2019 15:59
-
-
Save forensicmike/48b0471c9884ce551d39336bd7fd0566 to your computer and use it in GitHub Desktop.
(LINQPAD) Use an array of Android Package names to resolve their 'nice' names from the Google play store. Stores results in a SQLite db.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Resolve package names by scraping the Google play store. | |
| // The only modifications needed are to manipulate where data is accessed from. | |
| async void Main() | |
| { | |
| // Load your package names into ListOfPackageNames (see OPTION 1 or OPTION 2) | |
| var ListOfPackageNames = new List<string>(); | |
| // Change this to true if you want to store the outcomes in a database. | |
| var bStoreResults = true; | |
| // Path you want to use if the above is true. NOTE: This will be loaded | |
| var resultsDbPath = @"c:\temp\packageNames.db"; | |
| // ------------------------------------------------------------------------------------------------------ | |
| // OPTION 1: | |
| // If you're targetting a directory on disk (i.e. exported from the Android device, as in FOR585 Lab 5.1) | |
| var directoryToScan = @"G:\FOR585-Labs\Lab5.1\Android Device\"; | |
| ListOfPackageNames.AddRange(Directory.GetDirectories(directoryToScan).Select(x => new DirectoryInfo(x).Name)); | |
| // ------------------------------------------------------------------------------------------------------ | |
| // OPTION 2: | |
| // Load data from the clipboard (i.e. copied from Excel) | |
| //ListOfPackageNames.AddRange(Clipboard.GetText().Split('\n')); | |
| var alreadyKnown = new Dictionary<string,string>(); | |
| if (File.Exists(resultsDbPath)) | |
| { | |
| using (var con = new SQLiteConnection($"Data Source={resultsDbPath}")) | |
| { | |
| con.Open(); | |
| var cmd = new SQLiteCommand(@"SELECT package_name, app_name FROM packages", con); | |
| using (var reader = cmd.ExecuteReader()) | |
| { | |
| while (reader.Read()) | |
| { | |
| alreadyKnown.Add(reader["package_name"] as string, reader["app_name"] as string); | |
| } | |
| } | |
| con.Close(); | |
| } | |
| } | |
| var failed = new List<PackageResult>(); | |
| var succeeded = new List<PackageResult>(); | |
| using (var wc = new WebClient()) | |
| { | |
| foreach (var pkg in ListOfPackageNames) | |
| { | |
| var ak = string.Empty; | |
| if (alreadyKnown.TryGetValue(pkg, out ak)) | |
| { | |
| if (string.IsNullOrWhiteSpace(ak)) | |
| { | |
| failed.Add(new PackageResult() | |
| { | |
| AlreadyKnown = true, | |
| PackageName = pkg, | |
| AppName = string.Empty, | |
| }); | |
| } | |
| else | |
| { | |
| succeeded.Add(new PackageResult() | |
| { | |
| AlreadyKnown = true, | |
| PackageName = pkg, | |
| AppName = ak, | |
| }); | |
| Console.WriteLine($"{pkg} -> {ak}"); | |
| } | |
| continue; | |
| } | |
| try { | |
| var test = await wc.DownloadStringTaskAsync($"https://play.google.com/store/apps/details?id={pkg}"); | |
| var match = Regex.Match(test, @"itemprop=""name""><span >(?<appName>[\w\W]*?)</span>"); | |
| var appName = match.Groups["appName"].Value; | |
| succeeded.Add(new PackageResult() | |
| { | |
| PackageName = pkg, | |
| AppName = appName, | |
| AlreadyKnown = false, | |
| }); | |
| Console.WriteLine($"{pkg} -> {appName}"); | |
| } | |
| catch | |
| { | |
| failed.Add(new PackageResult() | |
| { | |
| PackageName = pkg, | |
| AppName = string.Empty, | |
| AlreadyKnown = false, | |
| }); | |
| } | |
| } | |
| } | |
| Console.WriteLine(Environment.NewLine + Environment.NewLine + "****************************************"); | |
| Console.WriteLine($"Failed app resolves: {string.Join(", ", failed.Select(x => x.PackageName))}"); | |
| // This is where we push all our results that aren't already known to us into the DB, if enabled | |
| if (bStoreResults) | |
| { | |
| using (var con = new SQLiteConnection($"Data Source={resultsDbPath}")) | |
| { | |
| con.Open(); | |
| new SQLiteCommand(@"CREATE TABLE IF NOT EXISTS packages (package_name VARCHAR, app_name VARCHAR);", con).ExecuteNonQuery(); | |
| var insCmd = new SQLiteCommand(@"INSERT INTO packages (package_name, app_name) VALUES(@pn, @an);", con); | |
| insCmd.Parameters.AddWithValue("pn", string.Empty); | |
| insCmd.Parameters.AddWithValue("an", string.Empty); | |
| var tx = con.BeginTransaction(); | |
| foreach (var item in succeeded.Where(x => !x.AlreadyKnown)) | |
| { | |
| insCmd.Parameters["pn"].Value = item.PackageName; | |
| insCmd.Parameters["an"].Value = item.AppName; | |
| insCmd.ExecuteNonQuery(); | |
| } | |
| foreach (var item in failed.Where(x => !x.AlreadyKnown)) | |
| { | |
| insCmd.Parameters["pn"].Value = item.PackageName; | |
| insCmd.Parameters["an"].Value = item.AppName; | |
| insCmd.ExecuteNonQuery(); | |
| } | |
| tx.Commit(); | |
| con.Close(); | |
| } | |
| } | |
| } | |
| public class PackageResult | |
| { | |
| public bool AlreadyKnown { get; set; } | |
| public string AppName { get; set; } | |
| public string PackageName { get; set; } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment