Кнопка Python «Больше» не работает - PullRequest
0 голосов
/ 25 октября 2019

Я пытался нажимать кнопку «Еще» для каждого отзыва, чтобы я мог расширить эти текстовые обзоры до полного содержания, а затем я пытаюсь очистить эти текстовые обзоры. Не нажимая кнопку «Еще», я получаю что-то вроде
«Эта комната была красивой и чистой. Расположение ... Подробнее».

Я попробовал несколько разных функций, чтобы понять это. такие как нажатие кнопки селена и ActionChain, но я думаю, что я не использую их должным образом. Может ли кто-нибудь помочь мне с этой проблемой?

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

from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver import ActionChains

#Incognito Mode
option=webdriver.ChromeOptions()
option.add_argument("--incognito")

#Open Chrome
driver=webdriver.Chrome(executable_path="C:/Users/chromedriver.exe",chrome_options=option)

#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 k in lists:

    driver.get(k)
    html =driver.page_source
    soup=BeautifulSoup(html,"html.parser")
    time.sleep(3)
    listing=soup.find_all("div", class_="review-container")

    for i in range(len(listing)):

        try:
            #First, I tried this but didn't work.
            #link = driver.find_element_by_link_text('More')
            #driver.execute_script("arguments[0].click();", link)

            #Second, I tried ActionaChains but didn't work.
            ActionChains(driver).move_to_element(i).click().perform()
        except:
            pass

        text_review=soup.find_all("div", class_="prw_rup prw_reviews_text_summary_hsx")
        text_review_inside=text_review[i].find("p", class_="partial_entry")
        review_text=text_review_inside.text

        print (review_text)

1 Ответ

1 голос
/ 25 октября 2019

Ваша самая большая ошибка во всем этом коде - 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 ---')
...