python - 如何创建面向对象的代码来替换 python 中的许多“尝试”循环
问题描述
我正在重复此代码,以便我可以从网站上抓取一些新闻。周末和节假日,网站不刷新,只有工作日的消息。
这是我为获取前一个工作日新闻的代码创建的解决方案,但我知道它不是正确的编程方式。
import smtplib, ssl
import datetime, time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException,StaleElementReferenceException, ElementClickInterceptedException
options = webdriver.ChromeOptions()
#options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)
driver.get('https://fiis.com.br/atualizacoes/')
driver.implicitly_wait(10)
time.sleep(2)
#here I try to close a new html popup that has been there since last week
try:
driver.find_element_by_xpath('/html/body/div[1]/div/button').click()
except NoSuchElementException:
print("NoSuchElementException")
try:
driver.find_element_by_xpath('/html/body/div[2]/div/button').click()
except NoSuchElementException:
print("NoSuchElementException")
except ElementClickInterceptedException:
try:
driver.find_element_by_xpath('/html/body/div[2]/div/button').click()
except NoSuchElementException:
print("NoSuchElementException")
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-type="date"]'))).click()
#here I try diferent dates, first a today minus 1, then today minus 2 ... until today minus 4
try:
today = datetime.date.today()
five_day = datetime.timedelta(days=-1)
d_N1 = today + five_day
d_N1_2 = d_N1.strftime('%Y-%m-%d')
d_N1_3 = d_N1.strftime('%d.%m.%Y')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, f'li[data-item="{d_N1_2}"]')))
driver.find_element_by_css_selector(f'li[data-item="{d_N1_2}"]').click()
except TimeoutException or NoSuchElementException:
try:
today = datetime.date.today()
five_day = datetime.timedelta(days=-2)
d_N1 = today + five_day
d_N1_2 = d_N1.strftime('%Y-%m-%d')
d_N1_3 = d_N1.strftime('%d.%m.%Y')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, f'li[data-item="{d_N1_2}"]')))
driver.find_element_by_css_selector(f'li[data-item="{d_N1_2}"]').click()
except TimeoutException or NoSuchElementException:
try:
today = datetime.date.today()
five_day = datetime.timedelta(days=-3)
d_N1 = today + five_day
d_N1_2 = d_N1.strftime('%Y-%m-%d')
d_N1_3 = d_N1.strftime('%d.%m.%Y')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, f'li[data-item="{d_N1_2}"]')))
driver.find_element_by_css_selector(f'li[data-item="{d_N1_2}"]').click()
except TimeoutException or NoSuchElementException:
try:
today = datetime.date.today()
five_day = datetime.timedelta(days=-3)
d_N1 = today + five_day
d_N1_2 = d_N1.strftime('%Y-%m-%d')
d_N1_3 = d_N1.strftime('%d.%m.%Y')
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, f'li[data-item="{d_N1_2}"]')))
driver.find_element_by_css_selector(f'li[data-item="{d_N1_2}"]').click()
except TimeoutException or NoSuchElementException:
driver.close()
driver.quit()
如果昨天的消息是avaiable,我不需要得到前一天。
未来4天不够,所以可以考虑一个更好的解决方案。
解决方案
你可以用这个替换try-blocks:
days_ago = -4
today = datetime.date.today()
for n in range(-1, days_ago-1, -1):
five_day = datetime.timedelta(days=n)
d_N1 = today + five_day
d_N1_2 = d_N1.strftime('%Y-%m-%d')
d_N1_3 = d_N1.strftime('%d.%m.%Y')
try:
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, f'li[data-item="{d_N1_2}"]')))
driver.find_element_by_css_selector(f'li[data-item="{d_N1_2}"]').click()
break
except TimeoutException, NoSuchElementException:
if n <= days_ago:
print(f"failed to fetch data for any date")
这是通过使用一个循环来工作的,该循环将运行n=-1, n=-2, n=-3, n=-4
并继续,直到所有n
值都用完,或者直到driver.find_element_by_css_selector
不产生异常(这是break
可以到达语句的唯一方法)。
推荐阅读
- bash - IntelliJ IDEA 中“在终端中执行”选项的意义
- get - 如何从固定位置恢复winscp中的大文件下载
- c# - 如何为多级注册组件
- typescript - 打字稿:与 React 功能组件中的接受道具混淆
- python - 在我的 python 代码中滚动多个(ex.100)骰子时出错。**包括示例**
- reactjs - React-datepicker TypeError:无法读取未定义的属性“值”
- javascript - Javascript - 提取位于两个特殊字符之间的字符串的一部分
- unity3d - Mirror/UNET c# - 即使使用命令和 ClientRpc 也没有对象权限 - 我错过了什么?
- python - 将用 python 编写的字符串转换为在 python 中执行。也可能是一个完整的脚本作为字符串,中间有用户输入
- arrays - 使用带有 vba 的变体数据类型时出现问题