【问题标题】:Selenium (python) how to best handle a page anomalySelenium(python)如何最好地处理页面异常
【发布时间】:2021-12-30 10:16:14
【问题描述】:

我正在抓取意大利网站上发布新法律 (Gazzetta Ufficiale) 的页面,以保存包含法律文本的最后一页。

我有一个循环,它构建了一个要下载的页面列表,并附上了一个完整工作的 cose 示例,它显示了我正在运行的问题(示例没有循环,我只是在做两个“获取”。

处理不显示“Visualizza”(显示)按钮但直接进入所需全文的稀有页面的最佳方法是什么?

希望代码能够自我解释和注释。提前感谢您,2022 年超级快乐!

import time
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome("/Users/bob/Documents/work/scraper/scrape_gu/chromedriver")

# showing the "normal" behaviour
driver.get(
    "https://www.gazzettaufficiale.it/atto/vediMenuHTML?atto.dataPubblicazioneGazzetta=2021-01-02&atto.codiceRedazionale=20A07300&tipoSerie=serie_generale&tipoVigenza=originario"
)
# this page has a "Visualizza" button, find it and click it.
bottoni = WebDriverWait(driver, 10).until(
    EC.visibility_of_all_elements_located(
        (By.XPATH, '//*[@id="corpo_export"]/div/input[1]')
    )
)
time.sleep(5)  # just to see the "normal" result with the "Visualizza" button
bottoni[0].click()  # now click it  and this shows the desired final webpage
time.sleep(5)  # just to see the "normal" desired result

# but unfortunately some pages directly get to the end result WITHOUT the "Visualizza" button.
# as an example see the following get
# showing the "normal" behaviour
driver.get(
    "https://www.gazzettaufficiale.it/atto/vediMenuHTML?atto.dataPubblicazioneGazzetta=2021-01-02&atto.codiceRedazionale=20A07249&tipoSerie=serie_generale&tipoVigenza=originario"
) # get a law page
time.sleep(
    5
)  #  as you can see we are now on the final desired full page WITHOUT the Visualizza button
# hence the following code, identical to that above will fail and timeout
bottoni = WebDriverWait(driver, 10).until(
    EC.visibility_of_all_elements_located(
        (By.XPATH, '//*[@id="corpo_export"]/div/input[1]')
    )
)
time.sleep(5)  # just to see the result
bottoni[0].click()  # and this shows the desired final webpage

# and the program abends with the following message
#  File "/Users/bob/Documents/work/scraper/scrape_gu/temp.py", line 33, in <module>
#    bottoni = WebDriverWait(driver, 10).until(
#  File "/Users/bob/opt/miniconda3/envs/scraping/lib/python3.8/site-packages/selenium/webdriver/support/wait.py", line 80, in until
#    raise TimeoutException(message, screen, stacktrace)
#  selenium.common.exceptions.TimeoutException: Message:

【问题讨论】:

    标签: python selenium web-scraping


    【解决方案1】:

    使用 tryexcept 块捕获异常 - 如果没有按钮直接提取文本 - Handling Exeptions

    ...
    urls = [
        'https://www.gazzettaufficiale.it/atto/vediMenuHTML?atto.dataPubblicazioneGazzetta=2021-01-02&atto.codiceRedazionale=20A07300&tipoSerie=serie_generale&tipoVigenza=originario',
        'https://www.gazzettaufficiale.it/atto/vediMenuHTML?atto.dataPubblicazioneGazzetta=2021-01-02&atto.codiceRedazionale=20A07249&tipoSerie=serie_generale&tipoVigenza=originario'
       ]
    
    
    data = []
    
    for url in urls:
        driver.get(url)
        try:
            bottoni = WebDriverWait(driver,1).until(
                EC.element_to_be_clickable(
                    (By.XPATH, '//input[@value="Visualizza"]')
                )
            )
            bottoni.click()
        except TimeoutException:
            print('no bottoni -')
    
        finally:
            data.append(driver.find_element(By.XPATH, '//body').text)
    
    driver.close()
    print(data)
    ...
    

    【讨论】:

    • 请不要裸除,而是捕获特定的异常。
    • @Loïc : 你的意思是except TimeoutException: 要注意,它是由wait 引起的,而不是由另一个引起的?
    • 是的,专门捕获selenium.common.exceptions.TimeoutException 以确保您不会捕获其他异常。例如,您可以在一个裸异常中捕获 KeyboardInterrupt 异常,防止脚本在按下 ctrl + c 时停止。
    • 能够找到确切的原因绝对有用 - 已经添加,非常感谢您指出
    • 也许对您的代码的一个小的改进是将 data.append 语句移动到 finally: 块中的 except: 块之后?
    【解决方案2】:

    首先,在这个任务中使用 selenium 是多余的。

    您可以使用 requestsaiohttp 加上 beautifulsoup 来做同样的事情,但这样会更快更容易编码。

    现在回到您的问题,有几个解决方案。

    最简单的是:

    • 捕获超时异常:如果没有找到按钮,则直接解析法律。
    • 在单击按钮或解析网页之前检查按钮是否存在:!driver.findElements(By.id("corpo_export")).isEmpty()

    但话又说回来,你会更容易摆脱硒并改用beautifulsoup。

    【讨论】:

    • 感谢您的建议 Loic。以上只是一个非常复杂的代码的一个非常小的sn-p,用于处理一个极其复杂和不规则的网站,其中必须模拟许多下拉框、按钮和其他东西。由于完全无知,我从 Selenium 开始,发现它比我以前使用 BS4 的尝试更容易理解。肯定会考虑你的建议。 2022 年快乐。
    猜你喜欢
    • 1970-01-01
    • 2020-04-25
    • 2011-04-08
    • 2017-05-24
    • 1970-01-01
    • 2021-05-13
    • 2011-01-29
    • 2019-04-04
    • 1970-01-01
    相关资源
    最近更新 更多