Очистка скрытых элементов в динамически изменяющемся html

#python #selenium #beautifulsoup

Вопрос:

Мне нужно извлечь некоторую информацию из динамически изменяющегося html. Веб-сайт, о котором идет речь, является : https://www.mitartlending.com/featuredartworks. Здесь, когда вы нажимаете на данное изображение и наводите курсор мыши на увеличенное изображение, появляется наложение текста. Я пытаюсь соскрести этот текст. После попытки сделать это с помощью BS я решил, что мне, вероятно, придется использовать селен. Как бы вы подошли к решению этой проблемы? До сих пор у меня было:

 from selenium import webdriver
driver = webdriver.Chrome('/Users/Abramo/SeleniumDrivers/chromedriver') 
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver.get('https://www.mitartlending.com/featuredartworks')

driver.implicitly_wait(3)

my_element = driver.find_element_by_xpath(f'/html/body/div[5]/div[2]/div/main/section/div/div/div/div[3]/div/div/div/div[1]/div/a/img')
my_element.click()                                        
   

copy_from = driver.find_element_by_class_name('sqs-lightbox-meta overlay-description-visible')
my_next_button = driver.find_element_by_class_name('sqs-lightbox-next')
 

Ответ №1:

Все данные находятся в атрибутах. Вам просто нужно извлечь соответствующие из них. Нет необходимости в накладных расходах на селен.

 import requests
from bs4 import BeautifulSoup as bs

r = requests.get('https://www.mitartlending.com/featuredartworks')
soup = bs(r.content, 'lxml')
results = {i['data-title']:' '.join(bs(i['data-description'], 'lxml').text.split('n')) for i in soup.select('.margin-wrapper > a')}
print(results)
 

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

1. могу я спросить, что означает «>a» в». margin-оболочке >> a»?

2. Это синтаксис селектора css. элемент с именем класса margin-wrapper , за которым сразу же следует элемент с именем тега a

3. ^^ за исключением a того, что является прямым потомком элемента с классом margin-wrapper

Ответ №2:

Вы можете найти любое из этих изображений по

 images = driver.find_elements_by_xpath('//img[contains(@class,'thumb-image loaded')]')
 

Так, например, нажать на второе изображение вы можете с помощью

 images[1].click()
 

Чтобы навести курсор на элемент, вы можете сделать это:

 from selenium.webdriver.common.action_chains import ActionChains

hover = ActionChains(driver).move_to_element(images[1])
hover.perform()
 

Теперь, когда текст появился, вы можете найти и получить его с помощью

 text = driver.find_elements_by_xpath('(//img[contains(@class,'thumb-image loaded')])[2]/..//p').text
 

То же самое можно сделать для любого другого изображения там.
В целом код будет выглядеть так:

 from selenium.webdriver.common.action_chains import ActionChains

images = driver.find_elements_by_xpath('//img[contains(@class,"thumb-image loaded")]')
images[1].click()

time.sleep(2)
hover = ActionChains(driver).move_to_element(images[1])
hover.perform()

time.sleep(2)
text = driver.find_elements_by_xpath('(//img[contains(@class,"thumb-image loaded")])[2]/..//p')
for t in text:
    print(t.text)
 

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