【问题标题】:Getting list of likers for an instagram post - Python & Selenium获取 Instagram 帖子的点赞者列表 - Python 和 Selenium
【发布时间】:2019-07-19 02:19:45
【问题描述】:

我正在训练网络抓取。为此,我挑战自己,获得所有在 Instagram 上点赞帖子的人的名单。 我的问题是我被困在我只能得到喜欢的前 11 个用户名的地步。在获得喜欢的同时,我找不到正确的方法来自动化滚动过程。


这是我在 Jupyter Notebook 中的过程(它还不能用作脚本):

from selenium import webdriver
import pandas as pd

driver = webdriver.Chrome()

driver.get('https://www.instagram.com/p/BuE82VfHRa6/')

userid_element = driver.find_elements_by_xpath('//*[@id="react-root"]/section/main/div/div/article/div[2]/section[2]/div/div/a')[0].click()

elems = driver.find_elements_by_xpath("//*[@id]/div/a")

users = []

for elem in elems:
    users.append(elem.get_attribute('title'))

print(users)

你们有什么想法吗?

非常感谢

【问题讨论】:

    标签: python selenium web-crawler instagram


    【解决方案1】:

    我猜 Instagram 网站最多使用 17 个喜欢的用户元素。
    所以,这是一个循环

    1. 从网页获取元素列表
    2. 保存到我的列表
    3. 向下滚动获取新元素
    4. 检查,这是最后一个滚动元素吗?
    driver.get('https://www.instagram.com/p/BuE82VfHRa6/')
    
    userid_element = driver.find_elements_by_xpath('//*[@id="react-root"]/section/main/div/div/article/div[2]/section[2]/div/div/a')[0].click()
    time.sleep(2)
    
    # here, you can see user list you want.
    # you have to scroll down to download more data from instagram server.
    # loop until last element with users table view height value.
    
    users = []
    
    height = driver.find_element_by_xpath("/html/body/div[3]/div/div[2]/div/div").value_of_css_property("padding-top")
    match = False
    while match==False:
        lastHeight = height
    
        # step 1
        elements = driver.find_elements_by_xpath("//*[@id]/div/a")
    
        # step 2
        for element in elements:
            if element.get_attribute('title') not in users:
                users.append(element.get_attribute('title'))
    
        # step 3
        driver.execute_script("return arguments[0].scrollIntoView();", elements[-1])
        time.sleep(1)
    
        # step 4
        height = driver.find_element_by_xpath("/html/body/div[3]/div/div[2]/div/div").value_of_css_property("padding-top")
        if lastHeight==height:
            match = True
    
    print(users)
    print(len(users))
    driver.quit()
    

    我在近 100 个喜欢的帖子中进行了测试,并且成功了。

    【讨论】:

    • 非常感谢您回到我身边。这绝对是滚动到列表的过程。但对我来说它在 instagram 中效果不佳,也许该平台擅长检测爬虫(?)。我应该检查是否可以设置滚动速度以查看可能影响结果的滚动速度。无论如何谢谢:)
    • @GrégoiredeKermel 在我的笔记本电脑环境中正常运行至少需要 0.1 秒。超过 2,500,000 个项目需要 2.9 小时......如果我使用 headless chrome driver,我不知道它是否更快。或者我不知道this 是否有帮助
    • 有帮助,谢谢!我注意到他们阻止我们获取用户的总列表。我在想我们修改第 3 步,将“time.sleep(0.2)”放入变量中,执行它,然后添加第 3 步之二:“如果 time.sleep 高于 0.2,则向上滚动50 像素,然后再次开始该过程,直到下一次过延迟或结束”。通过这样做,我很确定它可以让我们获得完整的列表。
    【解决方案2】:

    请尝试以下代码,如果可行,请告诉我。

    from selenium import webdriver
    driver = webdriver.Chrome()
    
    driver.get('https://www.instagram.com/p/BuE82VfHRa6/')
    
    elems = driver.find_elements_by_xpath("//a[@class='FPmhX notranslate TlrDj']")
    
    users = []
    
    for elem in elems:
        users.append(elem.get_attribute('title'))
        print('Title : ' +elem.get_attribute('title'))
    
    print(users)
    

    输出:-

    Title : kyliejenner
    Title : saturdayshade28
    Title : worldmeetzboy
    Title : mrokon
    Title : addieisaac
    Title : addieisaac
    Title : amber_doerksen
    Title : amber_doerksen
    Title : addieisaac
    Title : zayn6117
    Title : amber_doerksen
    Title : amber_doerksen
    Title : worldmeetzboy
    Title : worldmeetzboy
    Title : razvanpopic1301
    Title : johanna.trmn
    Title : johanna.trmn
    Title : johanna.trmn
    Title : americ.av
    Title : gabriellcostta1.0
    Title : gabriellcostta1.0
    Title : gabriellcostta1.0
    Title : worldmeetzboy
    Title : enactusepi
    Title : enactusepi
    [u'kyliejenner', u'saturdayshade28', u'worldmeetzboy', u'mrokon', u'addieisaac', u'addieisaac', u'amber_doerksen', u'amber_doerksen', u'addieisaac', u'zayn6117', u'amber_doerksen', u'amber_doerksen', u'worldmeetzboy', u'worldmeetzboy', u'razvanpopic1301', u'johanna.trmn', u'johanna.trmn', u'johanna.trmn', u'americ.av', u'gabriellcostta1.0', u'gabriellcostta1.0', u'gabriellcostta1.0', u'worldmeetzboy', u'enactusepi', u'enactusepi']
    

    【讨论】:

    • 感谢您的回答 :) 它实际上在做一些事情,但我正在寻找。执行此脚本时,我得到了最后一个 cmets 的用户名。我正在寻找的是所有喜欢该帖子的人的列表...我认为该过程是单击此 x-path (//*[@id]/div/a) 并滚动直到结束获得所有喜欢的列表。
    • 但是当运行这段代码时,它给了我所有链接帖子的用户。
    • 通过这样做,您将获得最后喜欢的人的列表(右侧面板上的列表)。但我希望获得所有 2,437,535 个赞的列表。当您点击“2,437,535 个赞”时,会出现一个包含所有赞的用户名的列表。
    • @KunduK 有没有办法获得在 Instagram 上喜欢和评论某些帖子的人的全名?
    【解决方案3】:

    我无法让代码按照预测的答案中发布的那样工作。因此,我在下面进行了改编,现在每个帖子获得了大约 500 个赞。

    def get_post_likers(shortcode):
        chrome = ch.initialize()
        chrome.get('https://www.instagram.com/p/' + shortcode + '/')
        chrome.execute_script("window.scrollTo(0, 1080)") 
        url = "/p/" + shortcode + "/liked_by/"
        time.sleep(2)
        like_link = chrome.find_element_by_xpath('//a[@href="'+url+'"]')
        like_link.click()
        time.sleep(2)
        users = []
        pb = chrome.find_element_by_xpath("//div[@role = 'dialog']/div[2]/div[1]/div[1]").value_of_css_property("padding-bottom")
        match = False
        while match==False:
            lastHeight = pb
    
            # step 1
            elements = chrome.find_elements_by_xpath("//*[@id]/div/a")
            # step 2
            for element in elements:
                if element.get_attribute('title') not in users:
                    users.append(element.get_attribute('title'))
            # step 3
            chrome.execute_script("return arguments[0].scrollIntoView();", elements[-1])
            time.sleep(1)
            # step 4
            pb = chrome.find_element_by_xpath("//div[@role = 'dialog']/div[2]/div[1]/div[1]").value_of_css_property("padding-bottom")
            if lastHeight==pb or len(users) >= 1500:
                match = True
        return users
    

    【讨论】:

      【解决方案4】:

      这对我有用:

      driver.get('https://www.instagram.com/p/BuE82VfHRa6/')
      
      time.sleep(2)
      
      userid_element = driver.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div[1]/article/div[3]/section[2]/div/div[2]/button').click()
      time.sleep(2)
      
      
      
      elems = driver.find_elements_by_xpath("//a[@class='FPmhX notranslate TlrDj']")
      
      users = []
      
      
      for i in range(10):
          i += 1
          if(i%10) == 9 :
              driver.find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div').click()
              actionChain.key_down(Keys.SPACE).key_up(Keys.SPACE).perform()
      
          print('/html/body/div[4]/div/div/div[2]/div/div/div['+str(i)+']/div[2]/div[1]/div/a')
          Title = driver.find_element_by_xpath('/html/body/div[4]/div/div/div[2]/div/div/div['+str(i)+']/div[2]/div[1]/div/a').get_attribute('title')
          users.append(Title)
          print('Title : ' + Title)
      
      print(users)
      

      【讨论】:

        【解决方案5】:

        我尝试了上述所有解决方案,但都没有奏效。我认为它们已经过时了。

        相反,我自己写了。它在 2020 年完美运行。

        此代码转到“用户名”地址并在个人资料中发布最新帖子并获得喜欢的用户。

        def getPosts():
            hrefs_in_view = driver.find_elements_by_tag_name('a')
            # finding relevant hrefs
            hrefs_in_view = [elem.get_attribute('href') for elem in hrefs_in_view
                 if '.com/p/' in elem.get_attribute('href')]
            
            return hrefs_in_view;
        
        
        
        
        
        def getLikers(username,limit,post=1):
            driver.get('https://www.instagram.com/' + username)
            time.sleep(1)
            users=[]
        
            #Get Latest Post
            driver.get(getPosts()[post])
            
            time.sleep(2)
            #Open Dialog
            followersLinkX = driver.find_element_by_xpath('//button[@class="sqdOP yWX7d     _8A5w5    "]')
            followersLinkX.click()
            time.sleep(1)
            #Get Dialog
            xxx = driver.find_element_by_xpath('//div[@role="dialog"]/div[1]/div[2]/div[1]/div[1]')
            #Focus on and Scroll
            xxx.click()
            # step 3
            actionChain = webdriver.ActionChains(driver)
        
          
        
            count = 0
            
            while(count < limit):
                for i in range(1,1000):
                    try:
                        users.append("https://www.instagram.com/" + driver.find_element_by_xpath('//div[@role="dialog"]/div[1]/div[2]/div[1]/div[1]/div['+ str(i) +']/div[2]/div[1]/div[1]').text) 
                        count+=1
                    except:
                        break
                actionChain.key_down(Keys.SPACE).key_up(Keys.SPACE).perform()
                time.sleep(0.5)  
        
            return users 
        

        为了运行likers = getLikers("deirvlon",100,1)

        【讨论】:

        • 我在这里尝试了一些解决方案,您的解决方案似乎更接近 instagram 网站今天的样子。虽然我无法检索实际的用户元素,但现在似乎有一个跨度,然后是一个“a”对象。您能否回顾并建议如何修改?我很困惑,谢谢!
        • 嗨,我再次检查了它是否正常工作。如果它给出错误可能是由于互联网加载速度。你可以增加“time.sleep(0.5)”睡眠时间来解决这个问题
        • 对不起,我忘记添加“getPosts()”方法。我认为这就是问题所在。现在我更新了。我希望它会工作)
        猜你喜欢
        • 2020-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-15
        • 2013-10-24
        • 2013-04-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多