CoderCastrov logo
CoderCastrov
Парсер

Парсинг лайков на Instagram

Парсинг лайков на Instagram
просмотров
3 мин чтение
#Парсер

Парсинг данных означает извлечение определенных данных с веб-сайта с учетом условий использования и конфиденциальности. А вы когда-нибудь задумывались, кто является вашими преданными подписчиками на Instagram? Я задумался об этом, и как студент компьютерных наук, я хотел узнать, есть ли способ получить эту информацию из своего собственного профиля. Следующий код предоставит пользователю список подписчиков, отсортированных в порядке убывания их лайков на ваших постах:

Вот пакеты, которые я использовал для этого кода:

from selenium import webdriver
import re
import time
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from webdriver_manager.chrome import ChromeDriverManager

Теперь нам нужно установить и вызвать драйвер Chrome, который фактически будет выполнять всю работу за нас.

driver = webdriver.Chrome(ChromeDriverManager().install())
login = "https://www.instagram.com/accounts/login/"
driver.get(login)
time.sleep(4)

Ниже приведен фрагмент кода, который дает боту доступ к вашему Instagram. Вам не понадобится эта часть, если вы пытаетесь получить лайки на общедоступном профиле.

driver.find_element_by_name("username").click()
driver.find_element_by_name("username").send_keys("") # здесь введите имя пользователя
driver.find_element_by_name("password").click()
driver.find_element_by_name("password").send_keys("") # здесь введите пароль
log_cl = driver.find_element_by_class_name("L3NKy") # кнопка входа
log_cl.click()   # нажимает кнопку входа
time.sleep(4)

Здесь мы говорим боту перейти на профиль, лайки которого мы пытаемся получить. Вы можете вставить туда любой общедоступный профиль или любой профиль, на который вы подписаны, но это нарушение частной жизни. Поэтому я решил использовать его только на своем собственном профиле.

url = 'http://instagram.com/almighty.opop/' # перейти на профиль
driver.get(url)
time.sleep(1)

Я решил сначала получить список всех подписчиков и поместить их в словарь с начальным количеством лайков, равным 0. Другой способ решить эту задачу - добавить имя лайкера при парсинге списка лайков.

# Получить список подписчиков
counter = 0
followers=[]
follower = int(driver.find_element_by_xpath('//*[@id="react-root"]/section/main/div/header/section/ul/li[2]/a/span').text) # Получить количество подписчиков

driver.find_element_by_css_selector('a.-nal3').click() # нажать на список подписчиков
time.sleep(1)
while len(followers) < follower-2:
    for follow in driver.find_elements_by_css_selector('div.d7ByH'):
        if not follow.text in followers:
            followers.append(follow.text)
            counter = counter + 1
    driver.find_element_by_css_selector('div.pbNvD.fPMEg.HYpXt').click()
    webdriver.ActionChains(driver).key_down(Keys.SPACE).key_up(Keys.SPACE).perform() # прокрутка вниз
    time.sleep(0.5)

print(len(followers))
follows = {}
for follower in followers:
    follows.update({follower:0})

Затем бот будет искать количество постов в этой строке

total = driver.find_element_by_css_selector('span.g47SY').text # получить количество постов
print(total)

Поскольку Instagram показывает только 12 постов при загрузке, я решил пройти через каждый пост отдельно, чтобы получить их ссылки и сохранить их в список.

driver.find_element_by_css_selector('div.eLAPa').click() # нажать на первый пост
time.sleep(1)
links=[]
for i in range(0,int(total)-1):
    links.append(driver.current_url)
    time.sleep(1)
    driver.find_element_by_css_selector('a._65Bje.coreSpriteRightPaginationArrow').click() # перейти к следующему посту

Теперь код вернет нас на профиль, чтобы мы могли начать перебирать список лайков каждого поста:

url = 'http://instagram.com/' # добавьте свое имя пользователя
driver.get(url)
time.sleep(1)

Я создал цикл for, который будет перебирать список постов. Код сначала получит общее количество лайков, добавит первый лайк, потому что он парсится отдельно, нажмет на список лайков

for i in links:
    driver.get(i)
    time.sleep(2)
    total = driver.find_element_by_css_selector('div.Nm9Fw').text # получить общее количество лайков
    print(total)

    users = {}

    users.update({total[total.find('by ')+3:total.find('and')]:1}) # добавить имя первого лайкера в список
    time.sleep(1)

    driver.find_element_by_css_selector('button.sqdOP.yWX7d._8A5w5').click() # нажать на список лайков первого поста
    time.sleep(1)

В том же цикле мы получаем количество лайков с помощью регулярных выражений и запускаем цикл while

actionChain = webdriver.ActionChains(driver)
likes = total[total.find('and ')+4:len(total)-7] 
count = 0
while len(users) != count:
    count = len(users)
    for like in driver.find_elements_by_css_selector('span.Jv7Aj.MqpiF'):
        if not like.text in users:
            users.update({like.text:1})
    try:
        myElem = WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div.pbNvD.fPMEg')))
    except TimeoutException:
        print('time is out')
        break
    driver.find_element_by_css_selector('div.pbNvD.fPMEg').click()
    webdriver.ActionChains(driver).key_down(Keys.SPACE).key_up(Keys.SPACE).perform()
    time.sleep(1)

Код будет искать имя лайкера в списке подписчиков, который мы создали, и увеличивать его на 1, когда находит его.

print(users)
print(len(users))

for follow in follows:
    if follow in users:
        follows[follow] = follows[follow] + 1

Мы сортируем словарь в порядке убывания и печатаем его.

print(sorted(follows.items(), key = lambda x:x[1],reverse=True))
driver.quit()