Невозможно очистить все фотографии даже после использования selenium для автоматизации прокрутки

#web-scraping #beautifulsoup #selenium-chromedriver #dynamic-html

#очистка веб-страниц #beautifulsoup #selenium-chromedriver #dynamic-html

Вопрос:

Я новичок в очистке веб-страниц. В настоящее время я работаю над проектом, в котором я хочу очистить все фотографии пользователя Instagram. У пользователя всего 521 сообщение, из-за чего я использовал selenium для прокрутки вниз до нижней части профиля. Но я все еще могу очистить только первые 37 фотографий. После дальнейшей проверки я обнаружил, что при прокрутке браузера вверх или вниз в исходном коде видны только первые несколько строк тегов img. По мере увеличения прокрутки ранее видимые теги img исчезают, и видны только следующие строки. Таким образом, в HTML-коде в любой момент времени отображается только определенное количество строк. Я сомневаюсь, что это причина, по которой я могу очистить только первые 37 фотографий.

Я хочу знать, как я могу очистить все фотографии профиля. Ниже я упомянул свой текущий код с использованием Beautiful Soup и Selenium. Здесь функция «scroll_down» использует selenium для прокрутки вниз до нижней части профиля. Я пытаюсь очистить все теги ‘img’ в функции «downloading_images», но, как уже упоминалось, я могу очистить только первые 37 фотографий.

 def downloading_images(self):
        soup = BeautifulSoup(self.driver.page_source,'html.parser')
        self.all_images = soup.findAll('img')
        print(len(self.all_images))

        for index,image in enumerate(self.all_images):
            filename = "image_"   str(index)   ".jpg"
            image_path = os.path.join(self.path,filename)
            link = image['src']
            print("Downloading image ", index)

            response = requests.get(link,stream = True)
            try:
                with open(image_path,'wb') as file:
                    shutil.copyfileobj(response.raw,file)
            except Exception as e:
                print(e)
                print('Could not download image no.', index)
                print('Image link',link)

def scroll_down(self):
        sleep(3)
        try:
            num_posts = self.driver.find_element_by_xpath('//span[text()[contains(.," posts")]]/span[@class="g47SY "]')
            str_num_posts = str(num_posts.text).replace(',','')
            self.int_num_posts = int(str_num_posts)

            if self.int_num_posts > 12:
                num_scrolls = int(self.int_num_posts/12)   3

            print(num_scrolls)
            sleep(3)
            try:
                for win in range(num_scrolls):
                    print(win)
                    self.driver.execute_script('window.scrollTo(0,document.body.scrollHeight);')
                    sleep(3)
            except Exception as e:
                self.error = True
                print(e)
        except Exception as e:
            self.error = True
            print(e)
  

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

Редактировать: Хорошо, я попытался очистить каждую прокрутку, и, похоже, это работает. Вот мой новый код.

 def downloading_images(self):

        print(len(self.all_images))



        for index,image in enumerate(self.all_images):
            filename = "image_"   str(index)   ".jpg"
            image_path = os.path.join(self.path,filename)
            link = image['src']
            print("Downloading image ", index)

            response = requests.get(link,stream = True)
            try:
                with open(image_path,'wb') as file:
                    shutil.copyfileobj(response.raw,file)
            except Exception as e:
                print(e)
                print('Could not download image no.', index)
                print('Image link',link)






    def scroll_down(self):
        sleep(3)
        try:
            num_posts = self.driver.find_element_by_xpath('//span[text()[contains(.," posts")]]/span[@class="g47SY "]')
            str_num_posts = str(num_posts.text).replace(',','')
            self.int_num_posts = int(str_num_posts)

            if self.int_num_posts > 12:
                num_scrolls = int(self.int_num_posts/12)   1

            else:
                num_scrolls = self.int_num_posts

            print(num_scrolls)
            sleep(3)
            try:
                soup = BeautifulSoup(self.driver.page_source,'html.parser')
                images = soup.findAll('img')
                
                self.all_images = images
                last_height = self.driver.execute_script("return document.body.scrollHeight")
                for win in range(num_scrolls):
                    print(win)
                    self.driver.execute_script('window.scrollTo(0,document.body.scrollHeight);')
                    sleep(3)
                    new_height = self.driver.execute_script("return document.body.scrollHeight")
                    if new_height == last_height:
                        break
                    soup = BeautifulSoup(self.driver.page_source,'html.parser')
                    images = soup.findAll('img')
                    self.all_images.extend(images[-12:])
                    last_height = new_height

                print(len(self.all_images))
            except Exception as e:
                self.error = True
                print(e)
        except Exception as e:
            self.error = True
            print(e)



    def search_target(self):
        try:
            search_bar = self.driver.find_element_by_xpath('//input[@class="XTCLo x3qfX "]')
            search_bar.send_keys(self.target_username)
            taget_profile_url = self.main_url   '/'   self.target_username   '/'
            self.driver.get(taget_profile_url)
        except Exception as e:
            self.error = True
            print(e)


    def close_notify_box(self):
        try:
            sleep(3)
            not_now_button = self.driver.find_element_by_xpath('//button[@class="aOOlW   HoLwm "]')
            not_now_button.click()
        except Exception:
            pass


    def log_in(self):
        try:
            log_in_button = self.driver.find_element_by_xpath('//p[@class="izU2O"]/a')
            log_in_button.click()
            sleep(3)
            user_name_input = self.driver.find_element_by_xpath('//input[@aria-label="Phone number, username, or email"]')
            user_name_input.send_keys(self.username)
            password_input = self.driver.find_element_by_xpath('//input[@aria-label="Password"]')
            password_input.send_keys(self.password)
            password_input.submit()
        except Exception as e:
            self.error = True
            print(e)
  

Я хотел бы знать, есть ли какие-либо альтернативные решения для этого. И является ли это эффективным решением. Спасибо.

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

1. возможно, вы захотите взглянуть на github.com/RonLek/InstaScraper

2. @JackFleeting Я попытался запустить код по указанной вами ссылке. Удаляются только последние 30 изображений. В моем коде аналогичная проблема, но он удаляет первые 37 изображений. Есть идеи, что может пойти не так?

3. Пока нет; Я попробовал другой, совершенно другой код в случайном Instagram-аккаунте, и мне удалось получить 33 изображения из 45. Я попробую еще раз завтра…

4. Хорошо, спасибо. Я пытаюсь это делать последние два дня. Надеюсь, я это выясню.