我开发了一个从气候网站抓取数据的程序。
该网站有一个选择日期的选项。在此基础上,它将显示大约 500 个站点的气候参数。
我的程序打开网站,通过 for 循环输入一系列日期,然后抓取网站中的数据。这很好用。
但是这个网站有一个固有的问题。对于某些较旧的日期,该网站有时会挂起。在这段时间内,我希望我的网络爬虫程序加载默认数据。但程序只是挂起。
import re
import pandas as pd
import requests
from urllib.request import urlopen
from bs4 import BeautifulSoup
import mechanicalsoup
import time
browser = mechanicalsoup.StatefulBrowser()
browser.session.timeout = (10,10)
url = "https://myclimate.com"
browser.open(url)
dateList = pd.date_range(start = '2023-01-01', end = '2023-02-02').strftime("%Y-%m-%d").tolist()
df = pd.DataFrame()
print("----")
for dte in dateList:
browser.select_form('form[action="https://myclimate.com]')
browser['date_on'] = dte
try:
response =browser.submit_selected()
print(response)
# my webscrap code and it will populate df
except requests.Timeout:
#df will be populated with default value
df.to_csv('data_year_J2023.csv')
当 myclimate.com 在某个日期挂起时,该程序也会挂起。
在我看来,一个简单的带有超时参数的post请求就足够了。如果超时生效或发生其他错误,只需插入默认数据框即可。
另一个观察结果是,在 HTTP 而不是 HTTPS 上生成结果更加可靠,可能是服务器存在问题。
import requests
import pandas as pd
url = 'https://beta-tnsmart.rimes.int/index.php/MIS/Rainfall/raingauge_stations'
data = []
for d in ['2021-05-01','2023-05-01','2024-05-01']:
try:
post_data = {
'date_on': d,
'search_submit': 'View Data'
}
response = requests.post(url, data=post_data, timeout=10)
if response.status_code == 200:
df = pd.read_html(response.content)[0].droplevel(0,axis=1)
df['Date'] = d
data.append(df)
else:
print(f'Request failed with status code: {response.status_code}')
data.append(pd.DataFrame({'Date':[d]}))
except requests.exceptions.Timeout:
print('The request timed out')
data.append(pd.DataFrame({'Date':[d]}))
except requests.exceptions.RequestException as e:
print(f'An error occurred: {e}')
data.append(pd.DataFrame({'Date':[d]}))
pd.concat(data, ignore_index=True)