Как добавить функцию для отслеживания перехода по ссылке с помощью selenium?

#python #selenium #selenium-webdriver #selenium-chromedriver

#python #selenium #selenium-webdriver #selenium-chromedriver

Вопрос:

Я написал короткую программу для автоматизации процесса перехода и сохранения профилей в LinkedIn.

Краткое:

  • Программа считывает текстовый файл с большим количеством URL-адресов LI.
  • Используя Selenium, он открывает их один за другим, затем нажимает кнопку «Открыть в навигаторе продаж»
  • Открывается новая вкладка, и на ней нужно нажать кнопку «Сохранить» и выбрать соответствующий список для сохранения.

У меня две основные проблемы:

  1. LinkedIn имеет 3 версии одной и той же страницы. Как я могу использовать условие, чтобы проверить, какая это версия страницы? (значение — если вы не можете найти эту кнопку, перейдите к следующей версии). Из того, что я видел, вы действительно не можете использовать функцию «If» с selenium, потому что это вызывает проблемы. Любые другие предложения?
  2. Что еще более важно, и причина, по которой я открыл эту тему — я хочу отслеживать «неудачные» ссылки. Допустим, у меня есть список из 1000 URL-адресов LI, и я запустил программу, чтобы сохранить их в своей учетной записи. Я хочу отслеживать те, которые он не сохранил или не смог открыть (неработающие ссылки, недоступная страница и т.д.). Чтобы выполнить это, я использовал CSV-файл и приказал программе сохранить все страницы, которые уже были сохранены в этой учетной записи, но это не решает мою проблему. Как я могу заставить его спасти их всех, а не только тех, кто уже был спасен? (Мне трудно выполнить это, потому что, когда страница отображается как «Недоступная», она переходит к следующей, и я не смог найти способ заставить его сохранить ее. Это усложняет работу с ним, потому что, когда я добавляю 500 или 1000 URL-адресов, я не могу сказать, какие из них сохраняются, а какие не сохраняются.

Вот код:

 import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import NoSuchElementException
import csv
import random



options = webdriver.ChromeOptions()
options.add_argument('--lang=EN')
options.add_argument("--start-maximized")
prefs = {"profile.default_content_setting_values.notifications" : 2}
options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(executable_path='assetschromedriver', chrome_options=options)
driver.get("https://www.linkedin.com/login?fromSignIn=true")

minDelay=input("n Please provide min delay in seconds : ")
maxDelay=input("n Please provide max delay in seconds : ")
listNumber=input("n Please provide list number : ")
outputFile=input('n save skipped as?: ')

count=0
closed=2
with open("links.txt", "r") as links:
    for link in links:
        try:
            driver.get(link.strip())
            sleep(3)
            driver.find_element_by_xpath("//button[@class='save-to-list-dropdown__trigger ph5 artdeco-button artdeco-button--primary artdeco-button--3 artdeco-button--pro artdeco-dropdown__trigger artdeco-dropdown__trigger--placement-bottom ember-view']").click()
            sleep(2)
            count =1
            if count==1:
                driver.find_element_by_xpath("//ul[@class='save-to-list-dropdown__content']//ul//li[" str(listNumber) "]").click()
            else:
                driver.find_element_by_xpath("//ul[@class='save-to-list-dropdown__content']//ul//li[1]").click()
            sleep(2)
            sleep(random.randint(int(minDelay), int(maxDelay)))
        except:
            if closed==0:
                driver.close()
                sleep(1)
                fileOutput=open(outputFile ".csv", mode='a', newline='', encoding='utf-8')
                file_writer = csv.writer(fileOutput, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
                file_writer.writerow([link.strip()])
                fileOutput.close()
print("Finished.")
 

Ответ №1:

Общий подход к использованию слушателей разного типа заключается в использовании EventFiringWebDriver . Смотрите пример здесь:

 from selenium import webdriver
from selenium.webdriver.support.abstract_event_listener import AbstractEventListener
from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver


class EventListener(AbstractEventListener):

    def before_click(self, element, driver):
        if element.tag_name == 'a':
            print('Clicking link:', element.get_attribute('href'))


if __name__ == '__main__':
    driver = EventFiringWebDriver(driver=webdriver.Firefox(), event_listener=EventListener())
    driver.get("https://webelement.click/en/welcome")
    link = driver.find_element_by_xpath('//a[text()="All Posts"]')
    link.click()
    driver.quit()
 

UPD:

В принципе, вашему делу действительно не нужен этот слушатель. Однако вы можете использовать ее. Допустим, у вас есть файл ссылки, например:

 https://google.com
https://invalid.url
https://duckduckgo.com/
https://sadfsdf.sdf
https://stackoverflow.com
 

Тогда путь с EventFiringWebDriver будет:

 from selenium import webdriver
from selenium.webdriver.support.abstract_event_listener import AbstractEventListener
from selenium.webdriver.support.event_firing_webdriver import EventFiringWebDriver

broken_urls = []


class EventListener(AbstractEventListener):

    def on_exception(self, exception, drv):
        broken_urls.append(drv.current_url)


if __name__ == '__main__':
    driver = EventFiringWebDriver(driver=webdriver.Firefox(), event_listener=EventListener())
    with open("links.txt", "r") as links:
        for link in links:
            try:
                driver.get(link.strip())
            except:
                print('Cannot reach the link', link.strip())

    print("Finished.")
    driver.quit()

    import csv
    with open('broken_urls.csv', 'w', newline='') as broken_urls_csv:
        wr = csv.writer(broken_urls_csv, quoting=csv.QUOTE_ALL)
        wr.writerow(broken_urls)
 

и без EventFiringWebDriver этого было бы:

 broken_urls = []

if __name__ == '__main__':
    from selenium import webdriver
    driver = webdriver.Firefox()
    with open("links.txt", "r") as links:
        for link in links:
            stripped_link = link.strip()
            try:
                driver.get(stripped_link)
            except:
                print('Cannot reach the link', link.strip())
                broken_urls.append(stripped_link)

    print("Finished.")
    driver.quit()

    import csv
    with open('broken_urls.csv', 'w', newline='') as broken_urls_csv:
        wr = csv.writer(broken_urls_csv, quoting=csv.QUOTE_ALL)
        wr.writerow(broken_urls)
 

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

1. Спасибо за ваш комментарий, @Alexey R. TBH, я не понял логики. Можете ли вы показать, как я могу реализовать это в своем коде? Я имею в виду, где я должен найти эту функцию и как я могу экспортировать все «ложные» результаты (все URL-адреса) в файл csv. Заранее спасибо за вашу помощь!