【问题标题】:selenium python webscrape fails after first iterationselenium python webscrape在第一次迭代后失败
【发布时间】:2016-10-13 06:02:24
【问题描述】:

我正在遍历tripadvisor 以保存cmets(非翻译,原始)和翻译的cmets(从葡萄牙语到英语)。 所以爬虫首先选择要显示的葡萄牙语cmets,然后像往常一样将它们一一转换成英文并将翻译后的cmets保存在com_中,而扩展的未翻译的cmets保存在expanded_cmets中。

代码在第一页上运行良好,但从第二页开始,它无法保存翻译后的 cmets。奇怪的是,它只翻译每个页面的第一条评论,甚至不保存它们。

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
com_=[]
expanded_comments=[]
date_=[]
driver = webdriver.Chrome("C:\Users\shalini\Downloads\chromedriver_win32\chromedriver.exe")
driver.maximize_window()
from bs4 import BeautifulSoup

def expand_reviews(driver):
    # TRYING TO EXPAND REVIEWS (& CLOSE A POPUP)    
    try:
        driver.find_element_by_class_name("moreLink").click()
    except:
        print "err"
    try:
        driver.find_element_by_class_name("ui_close_x").click()
    except:
        print "err2"
    try:
        driver.find_element_by_class_name("moreLink").click()
    except:
        print "err3"




def save_comments(driver):
    expand_reviews(driver)
    # SELECTING ALL EXPANDED COMMENTS
    #xpanded_com_elements=driver.find_elements_by_class_name("entry")
    time.sleep(3)
    #or i in expanded_com_elements:
    #   expanded_comments.append(i.text)
    spi=driver.page_source
    sp=BeautifulSoup(spi)
    for t in sp.findAll("div",{"class":"entry"}):
        if not t.findAll("p",{"class":"partial_entry"}):
            #print t
            expanded_comments.append(t.getText())
    # Saving review date
    for d in sp.findAll("span",{"class":"recommend-titleInline"}) :
        date=d.text
        date_.append(date_)


    # SELECTING ALL GOOGLE-TRANSLATOR links
    gt= driver.find_elements(By.CSS_SELECTOR,".googleTranslation>.link")

    # NOW PRINTING TRANSLATED COMMENTS
    for i in gt:
        try:
            driver.execute_script("arguments[0].click()",i)

            #com=driver.find_element_by_class_name("ui_overlay").text
            com= driver.find_element_by_xpath(".//span[@class = 'ui_overlay ui_modal ']//div[@class='entry']")
            com_.append(com.text)
            time.sleep(5)
            driver.find_element_by_class_name("ui_close_x").click().perform()
            time.sleep(5)
        except Exception as e:
            pass

# ITERATING THROIGH ALL 200 tripadvisor webpages and saving comments & translated comments             
for i in range(200):
    page=i*10
    url="https://www.tripadvisor.com/Airline_Review-d8729164-Reviews-Cheap-Flights-or"+str(page)+"-TAP-Portugal#REVIEWS"
    driver.get(url)
    wait = WebDriverWait(driver, 10)
    if i==0:
        # SELECTING PORTUGUESE COMMENTS ONLY # Run for one time then iterate over pages
        try:
            langselction = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span.sprite-date_picker-triangle")))
            langselction.click()
            driver.find_element_by_xpath("//div[@class='languageList']//li[normalize-space(.)='Portuguese first']").click()
            time.sleep(5)
        except Exception as e:
            print e

    save_comments(driver)

【问题讨论】:

  • 由于代码行太多需要分析,您能否定位问题?
  • @Andersson 的问题是,对于第一页(for 的第一个循环),所有原始和翻译的 cmets 都保存在各自的列表中( com_ & expand_cmets )但此后所有页面只有第一条评论被翻译,然后跳到下一页,而不翻译其余的 cmets。只需运行此代码并在第 3 次/第 4 次循环后分析列表 com_ 和 expand_cmets。这会给你一个想法
  • @Andersson 你能告诉我如何跳过那些英文的 cmets(因此他们下面没有“谷歌翻译”小部件)

标签: python selenium web-scraping


【解决方案1】:

你的代码有3个问题

  1. save_comments()方法内部,在driver.find_element_by_class_name("ui_close_x").click().perform(),webelement的方法click()不是ActionChain,所以你不能调用perform()。因此,该行应该是这样的:
driver.find_element_by_class_name("ui_close_x").click()
  1. 在方法save_comments() 中,在com= driver.find_element_by_xpath(".//span[@class = 'ui_overlay ui_modal ']//div[@class='entry']") 中,您可以找到尚未出现的元素。所以你必须在这条线之前添加等待。你的代码应该是这样的:
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, ".//span[@class = 'ui_overlay ui_modal ']//div[@class='entry']")))
com= driver.find_element_by_xpath(".//span[@class = 'ui_overlay ui_modal ']//div[@class='entry']")
  1. 有2个按钮可以打开评论,一个显示,一个隐藏。所以你必须跳过隐藏按钮。
if not i.is_displayed():
    continue
driver.execute_script("arguments[0].click()",i)

【讨论】:

  • 谢谢,这似乎有效。我检查了 4 个循环。但唯一的问题是 com_ 得到了重复的 cmets。我可以在运行您的代码本身时看到这一点,因为所有 cmets 都被翻译了两次。因此 len(com_) = 2 x len(expanded_cmets)。请解决这个问题。谢谢
  • @shalini 我不知道你为什么说它会打开每个评论两次。我认为只有第一个打开了两次,因为您的 CssSelector 在此页面上找到了所有谷歌翻译,并且它找到了与列表中的第一条评论相同的“最新评论”。为了只在评论中获得谷歌翻译,只需将 ID REVIEWS 添加到您的 CssSelector 表达式中。这是示例:gt= driver.find_elements(By.CSS_SELECTOR,"#REVIEWS .googleTranslation>.link")
  • 我很抱歉,但仍然是同样的问题。 cat_ 得到重复的 cmets,我可以看到每个评论的翻译都被点击了两次。因此,和以前一样,len(cat_) = 2 x len(expanded_cmets),这是唯一卡住的部分
  • @shalini 我已经更新了解决 2 个按钮问题的答案。请尝试。
  • 如果您尝试在第 4 次迭代后观察这两个列表,您会发现两个列表存在差异。两个列表之间应该存在一一对应关系,这不会发生
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2016-08-11
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 2012-09-16
  • 2016-04-13
相关资源
最近更新 更多