Ваша самая большая ошибка во всем этом коде - except: pass.
Без этого вы бы давно решили проблему. Код поднять сообщение об ошибке со всей информацией, но вы не можете увидеть его. Вы можете по крайней мере использовать
except Exception as ex:
print(ex)
Проблема в том, что move_to_element()
не будет работать с BeautifulSoup
элементами. Я должен быть элементом Selenium - как
link = driver.find_element_by_link_text('More')
ActionChains(driver).move_to_element(link)
Но после выполнения некоторых функций Selenium требуется некоторое время, чтобы это сделать - и Python должен ждать некоторое время.
Я не использую BeautifulSoup
чтобы получить данные, но если вы хотите их использовать, тогда получите driver.page_source
после нажатия на все ссылки. Или вам придется получать снова и снова driver.page_source
после каждого клика.
Иногда после нажатия вам, возможно, придется снова получать даже элементы Selenium - поэтому я сначала получаю запись, чтобы нажать More
, а позже я получаю partial_entry
для получения отзывов.
Я обнаружил, что при нажатии More
в первом обзоре отображается текст для всех обзоров, поэтому ему не нужно нажимать на все More
.
Протестировано сFirefox 69, Linux Mint 19.2, Python 3.7.5, Selenium 3.141
#from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver import ActionChains
import time
#Incognito Mode
option = webdriver.ChromeOptions()
option.add_argument("--incognito")
#Open Chrome
#driver = webdriver.Chrome(executable_path="C:/Users/chromedriver.exe",chrome_options=option)
driver = webdriver.Firefox()
#url I want to visit.
lists = ['https://www.tripadvisor.com/VacationRentalReview-g30196-d6386734-Hot_51st_St_Walk_to_Mueller_2BDR_Modern_sleeps_7-Austin_Texas.html']
for url in lists:
driver.get(url)
time.sleep(3)
link = driver.find_element_by_link_text('More')
try:
ActionChains(driver).move_to_element(link)
time.sleep(1) # time to move to link
link.click()
time.sleep(1) # time to update HTML
except Exception as ex:
print(ex)
description = driver.find_element_by_class_name('vr-overview-Overview__propertyDescription--1lhgd')
print('--- description ---')
print(description.text)
print('--- end ---')
# first "More" shows text in all reviews - there is no need to search other "More"
first_entry = driver.find_element_by_class_name('entry')
more = first_entry.find_element_by_tag_name('span')
try:
ActionChains(driver).move_to_element(more)
time.sleep(1) # time to move to link
more.click()
time.sleep(1) # time to update HTML
except Exception as ex:
print(ex)
all_reviews = driver.find_elements_by_class_name('partial_entry')
print('all_reviews:', len(all_reviews))
for i, review in enumerate(all_reviews, 1):
print('--- review', i, '---')
print(review.text)
print('--- end ---')
РЕДАКТИРОВАТЬ:
Чтобы пропустить ответы, я ищу все class="wrap"
и затем внутри каждой обертки я ищу class="partial_entry"
. У меня в каждой упаковке может быть только один отзыв и в итоге один ответ. Обзор имеет постоянный индекс [0]
. Некоторые обертки не сохраняют обзор, поэтому они дают пустой список - и я должен проверить его, прежде чем смогу получить элемент [0]
из списка.
all_reviews = driver.find_elements_by_class_name('wrap')
#print('all_reviews:', len(all_reviews))
for review in all_reviews:
all_entries = review.find_elements_by_class_name('partial_entry')
if all_entries:
print('--- review ---')
print(all_entries[0].text)
print('--- end ---')