你好Stack Overflow社区
我目前正在编写一个Python脚本,涉及从网页获取数据并将其存储在pandas DataFrame中。但是,我遇到了一个问题,DataFrame返回为null。我不能像预期的那样拿到记录。
下面是我正在使用的代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from bs4 import BeautifulSoup
import pandas as pd
def extract_data_from_table(table):
countries = []
regions_states = []
start_dates = []
end_dates = []
if table is not None:
for row in table.find_all('tr')[1:]:
columns = row.find_all('td')
if len(columns) >= 4:
countries.append(columns[0].text.strip())
regions_states.append(columns[1].text.strip())
start_dates.append(columns[2].text.strip())
end_dates.append(columns[3].text.strip())
return pd.DataFrame({
'Country': countries,
'Regions/States': regions_states,
'DST Start Date': start_dates,
'DST End Date': end_dates
})
else:
return None
url = "https://www.timeanddate.com/time/dst/2023.html"
# Create an instance of Chrome Options
options = Options()
options.add_argument("start-maximized")
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# Set up a WebDriverWait that will wait up to 1000 seconds for the table to appear
wait = WebDriverWait(driver, 1000)
driver.get(url)
# Wait for the table to appear
wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'table table--inner-borders-all table--left table--striped table--hover')))
# Get the page source and parse it with BeautifulSoup
soup = BeautifulSoup(driver.page_source, 'html.parser')
table = soup.find('table', class_='table table--inner-borders-all table--left table--striped table--hover')
df = extract_data_from_table(table)
driver.quit()
if df is not None:
print(df)
当我运行这段代码时,我希望看到一个DataFrame,其中填充了我试图获取的记录。然而,我得到的是一个空的DataFrame。我尝试通过检查记录源并确保数据确实存在来调试此问题,但我仍然无法填充DataFrame。
以下是我收到的错误消息:Traceback (most recent call last): File "/Users/rajeevranjanpandey/test.py", line 51, in <module> wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'table table--inner-borders-all table--left table--striped table--hover'))) File "/Users/rajeevranjanpandey/Library/Python/3.9/lib/python/site-packages/selenium/webdriver/support/wait.py", line 95, in until raise TimeoutException(message, screen, stacktrace)
我对Python、Selenium和pandas相对来说是个新手,所以我不确定我做错了什么。有谁能告诉我这里可能有什么问题吗?任何帮助将不胜感激。
感谢您的评分
以下是我尝试解决这个问题的步骤:
- 已检查URL以确保其正确且网页可访问。
- 已验证网页上是否存在我尝试抓取的表。
- 检查了网页HTML中表的类名,以确保它与我的代码中的类名匹配。
- 增加了WebDriverWait超时,以查看表是否需要更多时间加载。
尽管采取了这些步骤,我仍然遇到了同样的问题。我对Python、Selenium和pandas相对来说是个新手,所以我不确定我做错了什么。有谁能告诉我这里可能有什么问题吗?任何帮助将不胜感激。
感谢您的评分
2条答案
按热度按时间tcomlyy61#
下面是根据解析逻辑的完整解决方案。
不使用Selenium(使用requests+BeautifulSoup):
输出:
要确保结果是英语的,请将
headers
与请求沿着传递。headers={"Accept-Language": "en"}
[更新]:在下面的评论中回答您的第二个问题:
你可以简单地传递
datetime.now().year
来获得当前的年份。如果你明年运行它,URL将是https://www.timeanddate.com/time/dst/2024.html
等等。eqzww0vc2#
By.CLASS_NAME
只接受单个类值,不接受多个类值,而是使用By.CSS_SELECTOR
//等待表出现
//获取table元素的html
//使用in built方法获取 Dataframe ,无需使用soup和解析
或者你可以只使用两行代码,selenium甚至不需要。
快照: