private static List <Indeed> GetAllQuickies(string searchTerm, string location, string country, string apikey) { // Start position (startFromPosition) set to 0, meaning 1st Search Result page. string url = GenerateURL.Search(searchTerm, location, 0, country, apikey); //Get number of times to loop -- XmlDocument xmlDocument = ConsumeWebServiceRest(url); int numResults = xmlDocument.GetElementsByTagName("totalresults").Item(0) == null ? 0 : int.Parse(xmlDocument.GetElementsByTagName("totalresults").Item(0).InnerXml); XmlResult.TotalResults = numResults; int timesToIterate = (int)Math.Ceiling((decimal)XmlResult.TotalResults / 25); //Round up no matter what i.e. Math.Ceiling //Get number of times to loop -- //Get Everything from Web Service Query -- var quickies = new List <Indeed>(); // quick application pages Stopwatch totalTime = new Stopwatch(); totalTime.Start(); for (int i = 0; i < timesToIterate; i++) { Console.Clear(); Console.WriteLine(display + "\nLoading page... " + (i + 1) + "/" + timesToIterate); int pageStartFromRecord = i * 25; //25 records per page, way of receiving all records for current page url = GenerateURL.Search(searchTerm, location, pageStartFromRecord, country, apikey); xmlDocument = ConsumeWebServiceRest(url); XmlNodeList results = xmlDocument.GetElementsByTagName("result"); var batchIndeeds = ConvertXmlToObj(results); //Which are quickies && Is Snippet in English? foreach (var indeed in batchIndeeds) { if (indeed.IndeedApply) //If document consists of quick apply button, add to quicky list { quickies.Add(indeed); //Indeed - Quick Apply Application add to list } } //Which are quickies? // Define Quicky: A page returned by Indeed API that consists a "Quick Apply" button on it. } //Get Everything from Web Service Query -- return(quickies); }
public static void ViaIndeed(string searchTerm, string location, string countryCode, bool companySingleApply, string sql, User user, string apikey) { SqlConnection con = new SqlConnection(sql); // Append string with rest of display display = "Location: " + location + " Search Term(s): " + searchTerm; Console.Clear(); // Retrieve all pages with "Quick Apply" button on them ONLY var supersetQuickies = GetAllQuickies(searchTerm, location, countryCode, apikey); Console.Clear(); Console.WriteLine(display); // Reduce by configurations passed. Do not appy to // same company 2ce in a session (companySingleApply) var reducedQuckies = ReduceQuickies(supersetQuickies, companySingleApply, con); //There is nothing (new) to add therefore exit if (reducedQuckies.Count == 0) { return; } // Initialize Chrome Driver with Selenium API var driver = new ChromeDriver(); for (int j = 0; j < reducedQuckies.Count; j++) { // If already applied to company proceed loop if (IndeedSql.AlreadyAppliedCompany(reducedQuckies[j].Company, con)) { continue; } //Load the Job Posting page driver.Url = reducedQuckies[j].Url; string jk = reducedQuckies[j].Jobkey; // Passed from Indeed API query string jobTitle = reducedQuckies[j].JobTitle; // Passed from Indeed API query string hl = "en"; // English parameter string co = countryCode; //Get Variables to Store later from Job Posting page directly: string jobCompany = driver.FindElementByClassName("company").Text; string jobId = ""; try { jobId = driver.FindElements (By.CssSelector(".indeed-apply-widget"))[0] .GetAttribute("data-indeed-apply-jobid"); } catch { continue; } string apiToken = driver.FindElements(By.CssSelector(".indeed-apply-widget"))[0].GetAttribute( "data-indeed-apply-apitoken"); string postUrl = driver.FindElements(By.CssSelector(".indeed-apply-widget"))[0].GetAttribute( "data-indeed-apply-posturl"); string jobUrl = driver.FindElements(By.CssSelector(".indeed-apply-widget"))[0].GetAttribute( "data-indeed-apply-joburl"); string iaUid = driver.FindElement(By.Id("indeed-apply-js")) .GetAttribute("data-indeed-apply-qs") .Replace("vjtk=", ""); //iaUid == vjtk (variable)!!!!!! string advNum = driver.FindElements(By.CssSelector(".indeed-apply-widget"))[0].GetAttribute( "data-indeed-apply-advnum"); string email = string.Empty; try { email = driver.FindElements(By.CssSelector(".indeed-apply-widget"))[0].GetAttribute( "data-indeed-apply-email"); } catch {} // Generate URL is for the Application page ONLY string applyUrl = GenerateURL.ApplyUrl(email, postUrl, jk, jobTitle, jobUrl, jobCompany, jobId, apiToken, co, hl, advNum, iaUid); // Cover Letter Construction string pathToTemplate = user.CoverLetter; // Path to cover letter template. // Location of template string coverLetter = File.ReadAllText(pathToTemplate); // Simple replace to insert Location on the Fly (e.g. Richmond, VA) coverLetter = coverLetter.Replace("%varArea%", reducedQuckies[j].FormattedLocationFull); // Simple replace to insert Position on the Fly coverLetter = coverLetter.Replace("%varPos%", reducedQuckies[j].JobTitle); // Simple replace to insert Company Name (e.g. Bit Byte Buffer, LLC) coverLetter = coverLetter.Replace("%varCompany%", reducedQuckies[j].Company); // Workaround because driver will crash if you use for too long. // This may be resolved with newer versions of the driver count++; if (count == 10) { count = 0; driver.Close(); driver = new ChromeDriver(); driver.Url = reducedQuckies[j].Url; //Information Page } // Navigate to Application Page driver.Url = applyUrl; // Fill in My Name try // 1st Potential Id { driver.FindElementById("applicant.name").Clear(); driver.FindElementById("applicant.name").SendKeys(user.AppName); } catch { try // 2nd Potential Id (prefixed with "input-") { driver.FindElementById("input-applicant.name").Clear(); driver.FindElementById("input-applicant.name").SendKeys(user.AppName); } catch { // Can't insert name, therefore must not be a // quick apply (otherwise run should go smoothly) continue; } } // Fill in My Email try // 1st Potential Id { driver.FindElementById("applicant.email").Clear(); driver.FindElementById("applicant.email").SendKeys(user.AppEmail); } catch { try // 2nd Potential Id (prefixed with "input-") { driver.FindElementById("input-applicant.email").Clear(); driver.FindElementById("input-applicant.email").SendKeys(user.AppEmail); } catch { continue; } } // Fill in Phone Number try // 1st Potential Id { driver.FindElementById("applicant.phoneNumber").Clear(); driver.FindElementById("applicant.phoneNumber").SendKeys(user.AppPhone); } catch { try // 2nd Potential Id (prefixed with "input-") { driver.FindElementById("input-applicant.phoneNumber").Clear(); driver.FindElementById("input-applicant.phoneNumber").SendKeys(user.AppPhone); } catch { continue; } } //Upload Resume try { driver.FindElementById("resume") .SendKeys(user.AppResumePath); } catch { try { driver.FindElementById("ia-FilePicker-resume") .SendKeys(user.AppResumePath); } catch { continue; } } //Upload Supporting documents (e.g. Degree, Certifications, etc.) try { if (!string.IsNullOrEmpty(user.AppSupportingDoc1)) { driver.FindElementById("multattach1") .SendKeys(user.AppSupportingDoc1); } if (!string.IsNullOrEmpty(user.AppSupportingDoc2)) { driver.FindElementById("multattach2") .SendKeys(user.AppSupportingDoc2); } if (!string.IsNullOrEmpty(user.AppSupportingDoc3)) { driver.FindElementById("multattach3") .SendKeys(user.AppSupportingDoc3); } if (!string.IsNullOrEmpty(user.AppSupportingDoc4)) { driver.FindElementById("multattach4") .SendKeys(user.AppSupportingDoc4); } if (!string.IsNullOrEmpty(user.AppSupportingDoc5)) { driver.FindElementById("multattach5") .SendKeys(user.AppSupportingDoc5); } } catch { // stub: means there is no control for // supporting file uploads on page which is common } try { // Fill cover letter text box on form (attempt 1 with original Id) IJavaScriptExecutor js = driver; js.ExecuteScript("document.getElementById('applicant.applicationMessage').setAttribute('style', '')"); driver.FindElementById("applicant.applicationMessage").Click(); driver.FindElementById("applicant.applicationMessage").Clear(); driver.FindElementById("applicant.applicationMessage").SendKeys(coverLetter); } catch { try { // Fill cover letter text box on form (attempt 2 with new preixed "textarea-" Id) IJavaScriptExecutor js = driver; js.ExecuteScript("document.getElementById('textarea-applicant.applicationMessage').setAttribute('style', '')"); driver.FindElementById("textarea-applicant.applicationMessage").Click(); driver.FindElementById("textarea-applicant.applicationMessage").Clear(); driver.FindElementById("textarea-applicant.applicationMessage").SendKeys(coverLetter); } catch { // Could not identify an Application Message textbox to fill continue; } } //************ Apply Here ************* //Click on button submit try // Attempt 1, click button by CSS Class Selector { driver.FindElement(By.CssSelector(".button_content")).Click(); } catch { try // Attempt 2, click button by CSS ID Selector { driver.FindElement(By.CssSelector("#form-action-submit")).Click(); } catch { // Stub: Cannot find Application Button continue; } } // Let new page load for 1.5 seconds after clicking // submit application button Thread.Sleep(1500); try // Additional Yes/No questions added to US applications sometimes { driver.FindElement(By.Id("q_0")).SendKeys("Yes"); driver.FindElement(By.Id("apply")).Click(); } catch { // Stub: Not uncommon for this not to exist. In most cases it does not exist. } // Start Save process Stopwatch sw = new Stopwatch(); sw.Start(); while (true) { try { //Give it 2.5 minutes to upload all documents as max time permissible if (sw.ElapsedMilliseconds > 60000 * 2.5) { // Insert Failure message here!! SaveSubmission(reducedQuckies[j], false, con); //Changed to true as they are fine. Console.Clear(); Console.WriteLine(display); Console.WriteLine("\nFailed to apply: " + reducedQuckies[j].Company + " (" + reducedQuckies[j].JobTitle + ")"); break; // Exit while loop } driver.FindElement(By.Id("ia_success")); //Insert success message here!! Console.Clear(); Console.WriteLine(display); Console.WriteLine("\nSucceeded in applying to: " + reducedQuckies[j].Company + " (" + reducedQuckies[j].JobTitle + ")"); SaveSubmission(reducedQuckies[j], true, con); break; } catch { // Stub: recursion occurs until element found on page // and save is successful, or element is not found after // 2.5 minutes and record is saved as unsuccessful application } } // Sleep for 2 seconds before moving to next application Thread.Sleep(2000); } driver.Close(); driver.Dispose(); }