Почему эти данные не вставлены в мой словарь?

#python #selenium #dictionary

#python #селен #словарь

Вопрос:

В этом проекте по изучению Python я пытаюсь сохранить на свой компьютер изображения из учетной записи Instagram. Загвоздка в том, что я хочу сохранять изображения только в том случае, если они «высокого качества». Моим критерием для определения качества изображения является соотношение лайков и подписчиков.

После нескольких дней проб и ошибок мне удалось заставить работать часть моего кода, за исключением фильтрации отношения лайков к подписчикам.

Вот код, который я придумал:

 from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.options import Options

browser = webdriver.Chrome(executable_path=r"C:WebDriverbinchromedriver.exe")

post_links = []
selection = {}

def acceptCookies():
    ##accept cookies
    cookies = browser.find_element_by_xpath("/html/body/div[2]/div/div/div/div[2]/button[1]")
    time.sleep(1)
    cookies.click()
    time.sleep(2)


def getPostLinks():
    ##Get url of the 5 most recent posts
    url = 'https://www.instagram.com/earthpix/'
    browser.get(url)
    acceptCookies()
    element = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/div/header/section/ul/li[2]/a/span')
    followers = element.get_attribute('title')
    followers = followers.replace(' ', '')
    post = 'https://www.instagram.com/p/'
    links = [a.get_attribute('href') for a in browser.find_elements_by_tag_name('a')]
    for link in links:
        if post in link and link not in post_links:
            post_links.append(link)
            length = len(post_links)
            if length == 5:
                break
    time.sleep(10)
    for link in post_links:
        browser.get(link)
        try:
            phdiv = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div[1]/article/div[2]/div/div/div[1]/img')
            photo = phdiv.get_attribute('src')
            selection["photo_url"] = photo
            time.sleep(1)
            likes = browser.find_element_by_partial_link_text('likes').text
            likes = likes.replace(' ', '')
            global ratio
            ratio = int(likes)/int(followers)*100
            selection["ratio"] = ratio
            time.sleep(3)
        except:
            continue
        time.sleep(3)
    print(selection)

getPostLinks()
  

Приведенный выше код возвращает значение моего словаря «выбора» для ключа photo_url, но соотношение не добавляется в словарь.

Что может быть причиной этого?

Комментарии:

1. Первое, что нужно проверить, try это скрыть ошибки. У вас действительно никогда не должно быть пустого except: кода, и try s обычно не должен содержать столько кода. Укажите точную ошибку для перехвата и переносите только тот код, который вы ожидаете выдать. Вероятно, ошибка выдается до selection["ratio"] = ratio достижения.

2. Итак, вы наблюдаете, что выполняется только часть try блока? И вы не знаете, что происходит, потому что… except перехватывает любое исключение и игнорирует его? Может быть, вам стоит попробовать не делать этого , чтобы вы могли видеть, какое исключение было вызвано и почему. В любом случае, мое предположение: вы рассматривали, что произойдет, если у изображения будет ноль подписчиков?

Ответ №1:

Ваша проблема заключается в том, что вы пытаетесь получить количество лайков с помощью find_element_by_partial_link_text() , а Selenium не находит его. Из-за этого он всегда возвращает исключение и не присваивает изображению отношение.

Чтобы решить эту проблему, вам, вероятно, следует продолжать использовать xpath для определения количества лайков. Тогда код будет выглядеть так:

 from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.options import Options

browser = webdriver.Chrome(executable_path=r"C:WebDriverbinchromedriver.exe")

post_links = []
selection = {}

def acceptCookies():
    ##accept cookies
    cookies = browser.find_element_by_xpath("/html/body/div[2]/div/div/div/div[2]/button[1]")
    time.sleep(1)
    cookies.click()
    time.sleep(2)


def getPostLinks():
    ##Get url of the 5 most recent posts
    url = 'https://www.instagram.com/earthpix/'
    browser.get(url)
    acceptCookies()
    element = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/div/header/section/ul/li[2]/a/span')
    followers = element.get_attribute('title')
    followers = followers.replace(' ', '')
    post = 'https://www.instagram.com/p/'
    links = [a.get_attribute('href') for a in browser.find_elements_by_tag_name('a')]
    for link in links:
        if post in link and link not in post_links:
            post_links.append(link)
            length = len(post_links)
            if length == 5:
                break
    time.sleep(10)
    for link in post_links:
        browser.get(link)
        try:
            phdiv = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div[1]/article/div[2]/div/div/div[1]/img')
            photo = phdiv.get_attribute('src')
            selection["photo_url"] = photo
            time.sleep(1)
            likes = browser.find_element_by_xpath("/html/body/div[1]/section/main/div/div[1]/article/div[3]/section[2]/div/div/button/span").text
            likes = likes.replace(' ', '').replace(",", "")
            global ratio
            ratio = int(likes)/int(followers.replace(",", ""))*100
            selection["ratio"] = ratio
            time.sleep(3)
        except:
            continue
        time.sleep(3)
    print(selection)
    browser.quit()

getPostLinks()
  

Обратите внимание, что мне пришлось убрать запятые. Мне пришлось это сделать, потому что Instagram вставляет запятую в число лайков, чтобы сделать его более читаемым.

Еще одна вещь, которую я должен упомянуть, это то, что ваша функция acceptCookies не сработала для меня. Может быть, это потому, что я использовал Firefox, я не знаю. Но, в любом случае, я мог бы запустить код без него.

Ответ №2:

Dict — это ключ-значение. Один ключ = 1 значение. В вашем коде вы всегда используете один и тот же ключ (photo_url и ratio ) для каждой ссылки. Я бы предпочел попытаться вернуть список объектов dictionnaries, а не один словарь. Вот так:

  • Обратите внимание, что я не использую глобальные переменные
  • Обратите внимание, что я возвращаю список (all_selections) словарных объектов (mysel)
 from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
from selenium.webdriver.chrome.options import Options

browser = webdriver.Chrome(executable_path=r"C:WebDriverbinchromedriver.exe")

def acceptCookies():
    ##accept cookies
    cookies = browser.find_element_by_xpath("/html/body/div[2]/div/div/div/div[2]/button[1]")
    time.sleep(1)
    cookies.click()
    time.sleep(2)

def getPostLinks():
    post_links = []
    all_selections = []
    ##Get url of the 5 most recent posts
    url = 'https://www.instagram.com/earthpix/'
    browser.get(url)
    acceptCookies()
    element = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/div/header/section/ul/li[2]/a/span')
    followers = element.get_attribute('title')
    followers = followers.replace(' ', '')
    post = 'https://www.instagram.com/p/'
    links = [a.get_attribute('href') for a in browser.find_elements_by_tag_name('a')]
    for link in links:
        if post in link and link not in post_links:
            post_links.append(link)
            length = len(post_links)
            if length == 5:
                break
    time.sleep(10)
    for link in post_links:
        browser.get(link)
        try:
            myselc = {}
            phdiv = browser.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div[1]/article/div[2]/div/div/div[1]/img')
            photo = phdiv.get_attribute('src')
            mysel["photo_url"] = photo
            time.sleep(1)
            likes = browser.find_element_by_partial_link_text('likes').text
            likes = likes.replace(' ', '')
            global ratio
            ratio = int(likes)/int(followers)*100
            mysel["ratio"] = ratio
            all_selections.append(mysel)
            time.sleep(3)
        except:
            continue
    time.sleep(3)
    return all_selections
  

Ответ №3:

Я думаю, вы хотите сопоставить URL-адрес фотографии с его соотношением, не так ли?

 ...
time.sleep(1)
likes = browser.find_element_by_partial_link_text('likes').text
likes = likes.replace(' ', '')
global ratio
ratio = int(likes) / int(followers) * 100
selection[photo] = ratio
...