0

我正在尝试在 10 个网页中抓取一长串书籍。当循环第一次单击下一步 >按钮时,网站会显示登录覆盖,因此 selenium 无法找到目标元素。我已经尝试了所有可能的解决方案:

  1. 使用一些镀铬选项。
  2. 使用 try-except 单击叠加层上的X按钮。但它只出现一次(第一次单击下一步 >时)。问题是当我把这个 try-except 块放在while True:循环的末尾时,它变成了无限的,因为我continue在除了我不想打破循环。
  3. 向 Chrome 添加一些弹出窗口阻止程序扩展,但是当我运行代码时它们不起作用,尽管我使用options.add_argument('load-extension=' + ExtensionPath).

这是我的代码:

options = Options()
options.add_argument('start-maximized')
options.add_argument('disable-infobars')
options.add_argument('disable-avfoundation-overlays')
options.add_argument('disable-internal-flash')
options.add_argument('no-proxy-server')
options.add_argument("disable-notifications")
options.add_argument("disable-popup")
Extension = (r'C:\Users\DELL\AppData\Local\Google\Chrome\User Data\Profile 1\Extensions\ifnkdbpmgkdbfklnbfidaackdenlmhgh\1.1.9_0')
options.add_argument('load-extension=' + Extension)
options.add_argument('--disable-overlay-scrollbar')

driver = webdriver.Chrome(options=options)
driver.get('https://www.goodreads.com/list/show/32339._50_?page=')
wait = WebDriverWait(driver, 2)

review_dict = {'title':[], 'author':[],'rating':[]}


html_soup = BeautifulSoup(driver.page_source, 'html.parser')
prod_containers = html_soup.find_all('table', class_ = 'tableList js-dataTooltip')


while True:
   
    table =  driver.find_element_by_xpath('//*[@id="all_votes"]/table')

    for product in table.find_elements_by_xpath(".//tr"):
        
        for td in product.find_elements_by_xpath('.//td[3]/a'):
            title = td.text
            review_dict['title'].append(title)

        for td in product.find_elements_by_xpath('.//td[3]/span[2]'):
            author = td.text
            review_dict['author'].append(author)

        for td in product.find_elements_by_xpath('.//td[3]/div[1]'):
            rating = td.text[0:4]
            review_dict['rating'].append(rating)
            
    try:
        close = wait.until(EC.element_to_be_clickable((By.XPATH, '/html/body/div[3]/div/div/div[1]/button')))
        close.click()
        
    except NoSuchElementException:
        continue
                
    try:
        element = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'next_page')))
        element.click()
        
    except TimeoutException:    
        break
    
    
df = pd.DataFrame.from_dict(review_dict) 
df

任何帮助,例如如果我可以将循环更改为 for 循环单击下一步 >按钮直到结束而不是 while 循环,或者我应该在哪里放置 try-except 块以关闭覆盖,或者如果有Chromeoption可以禁用覆盖。提前致谢

4

1 回答 1

0

感谢您分享您的代码和您遇到问题的网站。我能够通过使用关闭登录模式xpath。我接受了这个挑战,并使用类对象分解了代码。

1 个对象用于selenium.webdriver.chrome.webdriver,另一个对象用于您要从中抓取数据的页面(https://www.goodreads.com/list/show/32339)。

在以下方法中,我使用了 Javascriptreturn arguments[0].scrollIntoView();方法并且能够滚动到页面上显示的最后一本书。完成后,我可以单击下一步按钮

def scroll_to_element(self, xpath : str):
        element = self.chrome_driver.find_element(By.XPATH, xpath)
        self.chrome_driver.execute_script("return arguments[0].scrollIntoView();", element)

def get_book_count(self):
        return self.chrome_driver.find_elements(By.XPATH, "//div[@id='all_votes']//table[contains(@class, 'tableList')]//tbody//tr").__len__()

def click_next_page(self):
        # Scroll to last record and click "next page"
        xpath = "//div[@id='all_votes']//table[contains(@class, 'tableList')]//tbody//tr[{0}]".format(self.get_book_count())
        self.scroll_to_element(xpath)
        self.chrome_driver.find_element(By.XPATH, "//div[@id='all_votes']//div[@class='pagination']//a[@class='next_page']").click()

单击“下一步”按钮后,我看到了模态显示。我能够找到xpath模态框并能够关闭模态框。

def is_displayed(self, xpath: str, int = 5):
        try:
            webElement = DriverWait(self.chrome_driver, int).until(
                DriverConditions.presence_of_element_located(locator = (By.XPATH, xpath))
            )
            
            return True if webElement != None else False
        except:
            return False

def is_modal_displayed(self):
        return self.is_displayed("//body[@class='modalOpened']")

def close_modal(self):
        self.chrome_driver.find_element(By.XPATH, "//div[@class='modal__content']//div[@class='modal__close']").click()
        if(self.is_modal_displayed()):
            raise Exception("Modal Failed To Close")

我希望这可以帮助您解决问题。

于 2020-10-13T06:31:12.157 回答