78 lines
2.6 KiB
Python
78 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from selenium import webdriver
|
|
from selenium.webdriver.chrome.service import Service
|
|
from selenium.webdriver.common.action_chains import ActionChains
|
|
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support import expected_conditions
|
|
from selenium.webdriver.support.wait import WebDriverWait
|
|
from webdriver_manager.chrome import ChromeDriverManager
|
|
|
|
|
|
class Instagram:
|
|
"""Interface for interacting with Instagram."""
|
|
|
|
def __init__(self):
|
|
self.webdriver = None
|
|
self.actiondriver = None
|
|
|
|
def setup(self) -> None:
|
|
"""Setup connection to Selenium and Instagram."""
|
|
driver = webdriver.Chrome(
|
|
service=Service(
|
|
ChromeDriverManager().install(),
|
|
),
|
|
)
|
|
self.webdriver = driver
|
|
self.actiondriver = ActionChains(self.webdriver)
|
|
|
|
def close(self) -> None:
|
|
self.webdriver.close()
|
|
|
|
def get_image_url_list(self, url: str) -> list[str]:
|
|
"""Get list of image urls from post."""
|
|
logging.debug('getting %s', url)
|
|
self.webdriver.get(url)
|
|
logging.debug('finished getting url')
|
|
# handle cookie popup
|
|
try:
|
|
logging.debug('waiting for cookie popup to appear')
|
|
# wait forpopup to appear
|
|
elem = WebDriverWait(
|
|
driver=self.webdriver,
|
|
timeout=60,
|
|
).until(
|
|
expected_conditions.presence_of_element_located(
|
|
(By.XPATH, "//*[text()='Decline optional cookies']"),
|
|
),
|
|
)
|
|
logging.debug('located button')
|
|
except TimeoutError:
|
|
logging.error('Timeout before cookie popup appeared.')
|
|
else:
|
|
elem.click()
|
|
logging.debug('clicked button')
|
|
# find image elements with src url matching Instagram's CDN
|
|
img_elem_list = self.webdriver.find_elements(
|
|
by=By.XPATH,
|
|
value=(
|
|
"//article[@role='presentation']"
|
|
"//div[@role='presentation']"
|
|
"//img[contains(@src,'https://scontent.cdninstagram.com/v/')]"
|
|
),
|
|
)
|
|
# extract src url
|
|
img_src_list = [
|
|
img_elem.get_attribute(
|
|
'src',
|
|
) for img_elem in img_elem_list
|
|
]
|
|
# remove src urls with size mathing profile images
|
|
img_src_list = [
|
|
img_src for img_src in img_src_list if 's150x150' not in img_src
|
|
]
|
|
logging.debug('located %s image urls', len(img_src_list))
|
|
return img_src_list
|