From c4d4bf3a25c5093d4c0689f6e1bb6ac63f4e4676 Mon Sep 17 00:00:00 2001 From: "abdurrahman.yildiz" Date: Thu, 3 Nov 2022 22:28:30 +0300 Subject: [PATCH] first init --- .gitignore | 20 +++ instabot-result.txt | 0 pom.xml | 23 ++++ src/main/java/org/yildiz/Main.java | 31 +++++ .../java/org/yildiz/instabot/InstaBot.java | 125 ++++++++++++++++++ 5 files changed, 199 insertions(+) create mode 100644 .gitignore create mode 100644 instabot-result.txt create mode 100644 pom.xml create mode 100644 src/main/java/org/yildiz/Main.java create mode 100644 src/main/java/org/yildiz/instabot/InstaBot.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..99ce4b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr diff --git a/instabot-result.txt b/instabot-result.txt new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9cd32ae --- /dev/null +++ b/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + org.example + instabot + 1.0-SNAPSHOT + + + 18 + 18 + + + + org.seleniumhq.selenium + selenium-java + 4.5.3 + + + + \ No newline at end of file diff --git a/src/main/java/org/yildiz/Main.java b/src/main/java/org/yildiz/Main.java new file mode 100644 index 0000000..6c45937 --- /dev/null +++ b/src/main/java/org/yildiz/Main.java @@ -0,0 +1,31 @@ +package org.yildiz; + +import org.yildiz.instabot.InstaBot; + +import java.io.FileWriter; +import java.io.IOException; + +public class Main { + + + public static void main(String[] args) { + System.setProperty("webdriver.chrome.driver", "C:\\instabot\\chromedriver.exe"); + final String USERNAME = "user_name"; + final String PASSWORD = "password"; + final int PIC_LIMIT = 100; + InstaBot instabot = new InstaBot(); + writeToFile("instabot-result.txt", instabot.startBot(USERNAME, PASSWORD, PIC_LIMIT)); + } + + public static void writeToFile(String fileName, String content) { + try { + FileWriter myWriter = new FileWriter(fileName); + myWriter.write(content); + myWriter.close(); + System.out.println("Successfully wrote to the file."); + } catch (IOException e) { + System.out.println("An error occurred."); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/yildiz/instabot/InstaBot.java b/src/main/java/org/yildiz/instabot/InstaBot.java new file mode 100644 index 0000000..f8b6673 --- /dev/null +++ b/src/main/java/org/yildiz/instabot/InstaBot.java @@ -0,0 +1,125 @@ +package org.yildiz.instabot; + +import org.openqa.selenium.*; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.FluentWait; +import org.openqa.selenium.support.ui.Wait; + +import java.time.Duration; +import java.util.*; +import java.util.NoSuchElementException; + +public class InstaBot { + private final String INSTA_HOME_PAGE = "https://www.instagram.com"; + + private final By usernameLocator = new By.ByCssSelector("input[name='username']"); + private final By passwordLocator = new By.ByCssSelector("input[name='password']"); + private final By loginButtonLocator = new By.ByCssSelector("button[type='submit']"); + private final By postsLocator = new By.ByCssSelector("article a[href*='/p/']"); + private final By profileLocator = new By.ByCssSelector("img[alt*='s profile picture']"); + + private WebDriver webDriver = new ChromeDriver(); + + public String startBot(String username, String password, int picLimit) { + try { + final String USER_PROFILE = INSTA_HOME_PAGE + "/" + username; + webDriver.manage().window().maximize(); + JavascriptExecutor jse = (JavascriptExecutor) webDriver; + + webDriver.get(INSTA_HOME_PAGE); + login(username, password); + waitTo(profileLocator); + webDriver.get(USER_PROFILE); + waitTo(postsLocator); + + Set picLinks = collectPicLinks(jse, picLimit); + + HashMap likeCounter = countLikes(jse, picLinks); + + String fanList = likeCounter.entrySet() + .stream() + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .toList() + .toString(); + + jse.executeScript("alert('" + fanList + "');"); + + return fanList; + } catch (Exception e) { + System.out.println(e); + return null; + } + } + + private void login(String username, String password) { + waitTo(usernameLocator); + webDriver.findElement(usernameLocator).sendKeys(username); + webDriver.findElement(passwordLocator).sendKeys(password); + webDriver.findElement(loginButtonLocator).click(); + } + + private Set collectPicLinks(JavascriptExecutor jse, int picLimit) throws InterruptedException { + Set picLinks = new HashSet<>(); + int index = 0; + do { + index = picLinks.size(); + if (index >= picLimit) { + break; + } + final List pics = webDriver.findElements(postsLocator); + final int minLimit = Math.min(picLimit, pics.size()); + for (int i = 0; i < minLimit; i++) { + picLinks.add(pics.get(i).getAttribute("href")); + } + scrollBy(jse); + Thread.sleep(3000l); + } while (index < picLimit && (index != picLinks.size() || index == 0)); + + return picLinks; + } + + private HashMap countLikes(JavascriptExecutor jse, Set picLinks) { + HashMap likeCounter = new HashMap<>(); + String originalWindow = webDriver.getWindowHandle(); + for (String pLink : picLinks) { + try { + webDriver.switchTo().newWindow(WindowType.TAB); + webDriver.get(pLink + "liked_by/"); + waitTo(profileLocator); + scrollBy(jse); + Thread.sleep(3000l); + List likedUsers = webDriver.findElements(By.cssSelector("main [alt$='profile picture']")); + for (WebElement u : likedUsers) { + String followerUsername = u.getAttribute("alt").replace("'s profile picture", ""); + if (likeCounter.containsKey(followerUsername)) { + likeCounter.put(followerUsername, likeCounter.get(followerUsername) + 1); + } else { + likeCounter.put(followerUsername, 1); + } + } + webDriver.close(); + webDriver.switchTo().window(originalWindow); + } catch (Exception e) { + System.out.println("ERROR OCCURED FOR: " + pLink); + } + } + + return likeCounter; + } + + private void scrollBy(JavascriptExecutor jse) { + //jse.executeScript("window.scrollBy(0,document.body.style.zoom = 0.5)"); + jse.executeScript("window.scrollBy(0,document.body.scrollHeight)"); + } + + private void waitTo(By locator) { + Wait wait = new FluentWait<>(webDriver) + .withTimeout(Duration.ofSeconds(15)) + .pollingEvery(Duration.ofSeconds(1)) + .ignoring(NoSuchElementException.class); + + wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(locator)); + } + +}