【问题标题】:Python click 'More' button is not workingPython单击“更多”按钮不起作用
【发布时间】:2019-10-25 01:01:41
【问题描述】:

我尝试为每条评论单击“更多”按钮,以便将这些文本评论扩展到完整内容,然后尝试抓取这些文本评论。没有点击“更多”按钮,我最终检索到的是类似
“这个房间很干净。位置很好”。

我尝试了一些不同的功能来解决这个问题,例如 selenium 按钮单击和 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)

【问题讨论】:

  • 你在所有这些代码中最大的错误是except: pass。没有这个,你很久以前就可以解决问题。代码引发包含所有信息的错误消息,但您看不到它。

标签: python selenium button click


【解决方案1】:

你在所有这些代码中最大的错误是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 ---')

【讨论】:

  • 您好,感谢您修改后的 cmets。但看起来我同时也在检索管理响应(用于评论的主机的 cmets)。文本评论和管理响应具有相同的 div 类,这就是原因。有什么办法不收集管理层的回应?
  • 还有其他搜索元素的功能,您可以创建更复杂的规则或功能。你甚至可以使用XPath。在每个 class="wrap" 中只有一个评论和一个管理回复 - 如果您首先找到所有“包裹”并且在每个“包裹”中搜索评论,那么首先将是您的评论 - all_reviews_in_wrap[0]
  • 嗨,有什么原因导致动作链在该列表的评论的第二页上不起作用?评论的第二页无法点击“更多”按钮。
猜你喜欢
  • 2017-08-18
  • 2019-12-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2018-05-02
相关资源
最近更新 更多