通过URL迭代

时间:2018-04-28 15:39:40

标签: python pandas web-scraping

我正在尝试通过迭代URL并将收集的数据附加到列表中来从网站抓取数据。我知道它不漂亮(非常新),但我很满意直到迭代:

for date in date_list: # iterate through dates
        weather_list = pd.read_html(base_url + 'KOWD' + '/' + year + '/' + month + '/' + day + end_url)

我知道在for语句中,我必须调用年,月,日,以便迭代它们 - 但我想通过在数据帧中声明它们,它们将被识别为列表。有人有建议吗?无法通过这个!

import pandas as pd
import csv
from datetime import datetime

base_url = 'https://www.wunderground.com/history/airport/'
end_url = '/DailyHistory.html?req_city=&req_state=&req_statename=&reqdb.zip=&reqdb.magic=&reqdb.wmo='

start_date = '1970, 1, 1'
end_date = '1970, 1, 3'

daterange = pd.date_range(start_date, end_date)

date_list = []
for single_date in daterange: # create list of dates
    date_list.append(single_date.strftime("%Y-%m-%d"))

date_list = pd.DataFrame(date_list, columns = ['date'])

date_list['year'], date_list['month'], date_list['day'] = zip(*date_list['date'].map(lambda x: x.split('-'))) # split date into parts
year = date_list['year']
month = date_list['month']
day = date_list['day']
#print(year)
#print(month)
#print(day)
#print(type(date_list))        
#print(date_list)

for date in date_list: # iterate through dates
    weather_list = pd.read_html(base_url + 'KOWD' + '/' + year + '/' + month + '/' + day + end_url)
    #print(type(weather_list))
    weather_list = weather_list[4] # this is the table of values I want
    weather_list.append(date)

2 个答案:

答案 0 :(得分:1)

变量yearmonthday属于<class 'pandas.core.series.Series'>类型。您需要在循环访问它们时访问它们。考虑下面的代码。

for i in range(0,len(date_list)): # iterate through dates
    weather_list = pd.read_html(base_url + 'KOWD' + '/' + year[i] + '/' + month[i] + '/' + day[i] + end_url)
    #print(type(weather_list))
    weather_list = weather_list[4] # this is the table of values I want
    weather_list.append(date_list.iloc[i])

注意:运行此代码后,您提到的IndexError已解决但我在weather_list = weather_list[4]行收到错误。我查了一下,len(weather_list)始终是4.绝对是一个单独的问题,因为在这种情况下必然会发生list index out of range

答案 1 :(得分:1)

只需迭代daterange中的日期:

daterange = pd.date_range(start_date, end_date)
url_template = base_url + 'KOWD/{d.year}/{d.month}/{d.day}' + end_url
for date in daterange:
    url = url_template.format(d=date)
    weather_list = pd.read_html(url)
    # etc.

如果这对您有用,那么您可以删除在数据框中存储日期的所有后续代码,将它们更改为字符串,并为年,月和日期创建单独的列。

如果您确实需要创建日期的数据框,则可以执行此操作:

date_list = pd.DataFrame(daterange, columns=['date'])
for k in ['year', 'month', 'day']:
    date_list[k] = date_list.apply(lambda r: getattr(r.date, k), axis=1)

然后你可以迭代抛出行。

for index, row in date_list.iterrows():
    url = url_template.format(d=row)
    weather_list = pd.read_html(url)
    # etc.

然后考虑您想要weather_list输出的格式。如果刮取的信息不适合包含在数据框中,那么作为{date: table}对的字典可能更有意义

编辑:例如,如果您想从每个页面中选择第3个表并将其与日期连接在一个数据帧中,您可以这样做:

weather_dict = {}
for date in daterange:
    table = pd.read_html(url, header=0)[2]
    table.set_index(table.columns.values[0], inplace=True)
    table.index.set_names(None, inplace=True)
    weather_dict[date] = table

weather_df = pd.concat(weather_dict)