我正在尝试将数据列表写入Excel电子表格。我在excel中有34列,我需要输入这些数据。第1列是city1,第2列是第2列,等等......
这是我用来检索电子表格所需的所有数据的脚本。
#!usr/bin/env python
import urllib
from datetime import datetime
from datetime import timedelta
date = datetime.now()
date1 = date + timedelta(days=1)
date2 = date + timedelta(days=2)
date3 = date + timedelta(days=3)
date4 = date + timedelta(days=4)
date5 = date + timedelta(days=5)
date6 = date + timedelta(days=6)
class city :
def __init__(self, city_name, link) :
self.name = city_name
self.url = link
self.high0 = 0
self.high1 = 0
self.high2 = 0
self.high3 = 0
self.high4 = 0
self.high5 = 0
self.high6 = 0
self.high7 = 0
self.low1 = 0
self.low2 = 0
self.low3 = 0
self.low4 = 0
self.low5 = 0
self.low6 = 0
self.low7 = 0
def retrieveTemps(self) :
filehandle = urllib.urlopen(self.url)
# get lines from result into array
lines = filehandle.readlines()
# (for each) loop through each line in lines
line_number = 0 # a counter for line number
for line in lines:
line_number = line_number + 1 # increment counter
# find string, position otherwise position is -1
position0 = line.rfind('title="{}"'.format(date.strftime("%A")))
position1 = line.rfind('title="{}"'.format(date1.strftime("%A")))
position2 = line.rfind('title="{}"'.format(date2.strftime("%A")))
position3 = line.rfind('title="{}"'.format(date3.strftime("%A")))
position4 = line.rfind('title="{}"'.format(date4.strftime("%A")))
position5 = line.rfind('title="{}"'.format(date5.strftime("%A")))
position6 = line.rfind('title="{}"'.format(date6.strftime("%A")))
if position0 > 0 :
self.high0 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low1 = lines[line_number + 18].split('&')[0].split('>')[-1]
if position1 > 0 :
self.high1 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low2 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position2 > 0 :
self.high2 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low3 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position3 > 0 :
self.high3 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low4 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position4 > 0 :
self.high4 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low5 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position5 > 0 :
self.high5 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low6 = lines[line_number + 19].split('&')[0].split('>')[-1]
self.low7 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position6 > 0 :
self.high6 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.high7 = lines[line_number + 4].split('&')[0].split('>')[-1]
break # done with loop, break out of it
filehandle.close()
#BRITISH COLUMBIA CITIES
def getCities():
c1 = city('Prince George', 'http://www.weatheroffice.gc.ca/city/pages/bc-79_metric_e.html')
c2 = city('Kamloops', 'http://www.weatheroffice.gc.ca/city/pages/bc-45_metric_e.html')
c3 = city('Blue River', 'http://www.weatheroffice.gc.ca/city/pages/bc-22_metric_e.html')
c4 = city('High Level', 'http://www.weatheroffice.gc.ca/city/pages/ab-24_metric_e.html')
c5 = city('Peace River', 'http://www.weatheroffice.gc.ca/city/pages/ab-25_metric_e.html')
c6 = city('Jasper', 'http://www.weatheroffice.gc.ca/city/pages/ab-70_metric_e.html')
c7 = city('Edmonton', 'http://www.weatheroffice.gc.ca/city/pages/ab-50_metric_e.html')
c8 = city('Calgary', 'http://www.weatheroffice.gc.ca/city/pages/ab-52_metric_e.html')
#SASKATCHEWAN CITIES
c9 = city('Biggar', 'http://www.weatheroffice.gc.ca/city/pages/sk-2_metric_e.html')
c10 = city('Saskatoon', 'http://www.weatheroffice.gc.ca/city/pages/sk-40_metric_e.html')
c11 = city('Melville', 'http://www.weatheroffice.gc.ca/city/pages/sk-8_metric_e.html')
c12 = city('Canora', 'http://www.weatheroffice.gc.ca/city/pages/sk-3_metric_e.html')
c13 = city('Yorkton', 'http://www.weatheroffice.gc.ca/city/pages/sk-33_metric_e.html')
#MANITOBA CITIES
c14 = city('Winnipeg', 'http://www.weatheroffice.gc.ca/city/pages/mb-38_metric_e.html')
c15 = city('Sprague', 'http://www.weatheroffice.gc.ca/city/pages/mb-23_metric_e.html')
#ONTARIO CITIES
c16 = city('Thunder Bay', 'http://www.weatheroffice.gc.ca/city/pages/on-100_metric_e.html')
c17 = city('Sioux Lookout', 'http://www.weatheroffice.gc.ca/city/pages/on-135_metric_e.html')
c18 = city('Armstrong', 'http://www.weatheroffice.gc.ca/city/pages/on-111_metric_e.html')
c19 = city('Hornepayne', 'http://www.weatheroffice.gc.ca/city/pages/on-78_metric_e.html')
c20 = city('Sudbury', 'http://www.weatheroffice.gc.ca/city/pages/on-40_metric_e.html')
c21 = city('South Parry', 'http://www.weatheroffice.gc.ca/city/pages/on-103_metric_e.html')
c22 = city('Toronto', 'http://www.weatheroffice.gc.ca/city/pages/on-143_metric_e.html')
c23 = city('Kingston', 'http://www.weatheroffice.gc.ca/city/pages/on-69_metric_e.html')
c24 = city('Cornwall', 'http://www.weatheroffice.gc.ca/city/pages/on-152_metric_e.html')
#QUEBEC CITIES
c25 = city('Montreal', 'http://www.weatheroffice.gc.ca/city/pages/qc-147_metric_e.html')
c26 = city('Quebec', 'http://www.weatheroffice.gc.ca/city/pages/qc-133_metric_e.html')
c27 = city('La Tuque', 'http://www.weatheroffice.gc.ca/city/pages/qc-154_metric_e.html')
c28 = city('Saguenay', 'http://www.weatheroffice.gc.ca/city/pages/qc-166_metric_e.html')
c29 = city('Riviere-du-loup', 'http://www.weatheroffice.gc.ca/city/pages/qc-108_metric_e.html')
#NOVA SCOTIA CITIES
c30 = city('Truro', 'http://www.weatheroffice.gc.ca/city/pages/ns-25_metric_e.html')
c31 = city('Halifax', 'http://www.weatheroffice.gc.ca/city/pages/ns-19_metric_e.html')
#NEW BRUNSWICK CITIES
c32 = city('Edmundston', 'http://www.weatheroffice.gc.ca/city/pages/nb-32_metric_e.html')
c33 = city('Moncton', 'http://www.weatheroffice.gc.ca/city/pages/nb-36_metric_e.html')
c34 = city('Sarnia', 'http://www.weatheroffice.gc.ca/city/pages/on-147_metric_e.html')
cities = []
cities.append(c1)
cities.append(c2)
cities.append(c3)
cities.append(c4)
cities.append(c5)
cities.append(c6)
cities.append(c7)
cities.append(c8)
cities.append(c9)
cities.append(c10)
cities.append(c11)
cities.append(c12)
cities.append(c13)
cities.append(c14)
cities.append(c15)
cities.append(c16)
cities.append(c17)
cities.append(c18)
cities.append(c19)
cities.append(c20)
cities.append(c21)
cities.append(c22)
cities.append(c23)
cities.append(c24)
cities.append(c25)
cities.append(c26)
cities.append(c27)
cities.append(c28)
cities.append(c29)
cities.append(c30)
cities.append(c31)
cities.append(c32)
cities.append(c33)
cities.append(c34)
return (cities)
然后我运行此脚本将所有数据导出到excel文件:
#!/usr/bin/env python
from xlutils.copy import copy
from xlrd import open_workbook
import canada
#import os
#os.chdir("/data/ops/Ops Documents/MexTemps")
cities = canada.getCities()
for c in cities :
c.retrieveTemps()
##
# writing to excel
##
file_name = 'fcst_hilo_TEST.xls'
new_file_name = 'fcst_hilo.xls'
row = 1
# column constants
high0_col = 1
low1_col = 2
high1_col = 3
low2_col = 4
high2_col = 5
low3_col = 6
high3_col = 7
low4_col = 8
high4_col = 9
low5_col = 10
high5_col = 11
low6_col = 12
high6_col = 13
low7_col = 14
high7_col = 15
workbook_file = None
try :
# currently xlwt does not implement this option for xslx files
workbook_file = open_workbook(file_name, formatting_info=True)
except :
workbook_file = open_workbook(file_name)
workbook = copy(workbook_file)
sheet = workbook.get_sheet(0)
for c in cities :
sheet.write(row, high0_col, c.high0)
sheet.write(row, low1_col, c.low1)
sheet.write(row, high1_col, c.high1)
sheet.write(row, low2_col, c.low2)
sheet.write(row, high2_col, c.high2)
sheet.write(row, low3_col, c.low3)
sheet.write(row, high3_col, c.high3)
sheet.write(row, low4_col, c.low4)
sheet.write(row, high4_col, c.high4)
sheet.write(row, low5_col, c.low5)
sheet.write(row, high5_col, c.high5)
sheet.write(row, low6_col, c.low6)
sheet.write(row, high6_col, c.high6)
sheet.write(row, low7_col, c.low7)
sheet.write(row, high7_col, c.high7)
workbook.save(new_file_name)
当我运行这个脚本时,它将最后一个城市(c34)的所有数据输入第一行(应该是第一个城市c1)。它在第一个脚本中循环运行,但只将它遇到的最后一行导出到excel电子表格中。关于如何让它为循环中的所有内容输入数据的任何想法?谢谢!
编辑:
我需要做的最后一件事是将每个城市分配到一个单独的列。例如:“city1”需要转到第2列,“city2”转到第4列,“city3”转到第8列等等......有什么想法吗?
答案 0 :(得分:1)
这会有所帮助:
class city(object):
def __init__(self, city_name, link) :
self.name = city_name
self.url = link
self.high0 = 0
self.high1 = 0
self.high2 = 0
self.high3 = 0
self.high4 = 0
self.high5 = 0
self.high6 = 0
self.high7 = 0
self.low1 = 0
self.low2 = 0
self.low3 = 0
self.low4 = 0
self.low5 = 0
self.low6 = 0
self.low7 = 0
def retrieveTemps(self) :
filehandle = urllib.urlopen(self.url)
# get lines from result into array
lines = filehandle.readlines()
filehandle.close()
# (for each) loop through each line in lines
for line_number, line in enumerate(lines, start=1):
# find string, position otherwise position is -1
position0 = line.rfind('title="{}"'.format(date.strftime("%A")))
position1 = line.rfind('title="{}"'.format(date1.strftime("%A")))
position2 = line.rfind('title="{}"'.format(date2.strftime("%A")))
position3 = line.rfind('title="{}"'.format(date3.strftime("%A")))
position4 = line.rfind('title="{}"'.format(date4.strftime("%A")))
position5 = line.rfind('title="{}"'.format(date5.strftime("%A")))
position6 = line.rfind('title="{}"'.format(date6.strftime("%A")))
if position0 > 0 :
self.high0 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low1 = lines[line_number + 18].split('&')[0].split('>')[-1]
if position1 > 0 :
self.high1 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low2 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position2 > 0 :
self.high2 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low3 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position3 > 0 :
self.high3 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low4 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position4 > 0 :
self.high4 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low5 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position5 > 0 :
self.high5 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.low6 = lines[line_number + 19].split('&')[0].split('>')[-1]
self.low7 = lines[line_number + 19].split('&')[0].split('>')[-1]
if position6 > 0 :
self.high6 = lines[line_number + 4].split('&')[0].split('>')[-1]
self.high7 = lines[line_number + 4].split('&')[0].split('>')[-1]
break # done with loop, break out of it
def getCities():
return [
#BRITISH COLUMBIA CITIES
city('Prince George', 'http://www.weatheroffice.gc.ca/city/pages/bc-79_metric_e.html'),
city('Kamloops', 'http://www.weatheroffice.gc.ca/city/pages/bc-45_metric_e.html'),
city('Blue River', 'http://www.weatheroffice.gc.ca/city/pages/bc-22_metric_e.html'),
# Alberta
city('High Level', 'http://www.weatheroffice.gc.ca/city/pages/ab-24_metric_e.html'),
city('Peace River', 'http://www.weatheroffice.gc.ca/city/pages/ab-25_metric_e.html'),
city('Jasper', 'http://www.weatheroffice.gc.ca/city/pages/ab-70_metric_e.html'),
city('Edmonton', 'http://www.weatheroffice.gc.ca/city/pages/ab-50_metric_e.html'),
city('Calgary', 'http://www.weatheroffice.gc.ca/city/pages/ab-52_metric_e.html'),
#SASKATCHEWAN CITIES
city('Biggar', 'http://www.weatheroffice.gc.ca/city/pages/sk-2_metric_e.html'),
city('Saskatoon', 'http://www.weatheroffice.gc.ca/city/pages/sk-40_metric_e.html'),
city('Melville', 'http://www.weatheroffice.gc.ca/city/pages/sk-8_metric_e.html'),
city('Canora', 'http://www.weatheroffice.gc.ca/city/pages/sk-3_metric_e.html'),
city('Yorkton', 'http://www.weatheroffice.gc.ca/city/pages/sk-33_metric_e.html'),
#MANITOBA CITIES
city('Winnipeg', 'http://www.weatheroffice.gc.ca/city/pages/mb-38_metric_e.html'),
city('Sprague', 'http://www.weatheroffice.gc.ca/city/pages/mb-23_metric_e.html'),
#ONTARIO CITIES
city('Thunder Bay', 'http://www.weatheroffice.gc.ca/city/pages/on-100_metric_e.html'),
city('Sioux Lookout', 'http://www.weatheroffice.gc.ca/city/pages/on-135_metric_e.html'),
city('Armstrong', 'http://www.weatheroffice.gc.ca/city/pages/on-111_metric_e.html'),
city('Hornepayne', 'http://www.weatheroffice.gc.ca/city/pages/on-78_metric_e.html'),
city('Sudbury', 'http://www.weatheroffice.gc.ca/city/pages/on-40_metric_e.html'),
city('South Parry', 'http://www.weatheroffice.gc.ca/city/pages/on-103_metric_e.html'),
city('Toronto', 'http://www.weatheroffice.gc.ca/city/pages/on-143_metric_e.html'),
city('Kingston', 'http://www.weatheroffice.gc.ca/city/pages/on-69_metric_e.html'),
city('Cornwall', 'http://www.weatheroffice.gc.ca/city/pages/on-152_metric_e.html'),
city('Sarnia', 'http://www.weatheroffice.gc.ca/city/pages/on-147_metric_e.html'),
#QUEBEC CITIES
city('Montreal', 'http://www.weatheroffice.gc.ca/city/pages/qc-147_metric_e.html'),
city('Quebec', 'http://www.weatheroffice.gc.ca/city/pages/qc-133_metric_e.html'),
city('La Tuque', 'http://www.weatheroffice.gc.ca/city/pages/qc-154_metric_e.html'),
city('Saguenay', 'http://www.weatheroffice.gc.ca/city/pages/qc-166_metric_e.html'),
city('Riviere-du-loup', 'http://www.weatheroffice.gc.ca/city/pages/qc-108_metric_e.html'),
#NOVA SCOTIA CITIES
city('Truro', 'http://www.weatheroffice.gc.ca/city/pages/ns-25_metric_e.html'),
city('Halifax', 'http://www.weatheroffice.gc.ca/city/pages/ns-19_metric_e.html'),
#NEW BRUNSWICK CITIES
city('Edmundston', 'http://www.weatheroffice.gc.ca/city/pages/nb-32_metric_e.html'),
city('Moncton', 'http://www.weatheroffice.gc.ca/city/pages/nb-36_metric_e.html'),
]
你肯定需要这个:
for row, c in enumerate(cities, start=1):
看起来你不是在循环中递增行,所以这样可以解决这个问题。
答案 1 :(得分:1)
我最初在您之前的问题上回答了这个问题(我已经阅读了足够的评论来查看潜在的问题,但不是那个说你会问另外一个问题的问题)。 hughdbrown答案的第二个代码块显示了关键的洞察力,您应该使用enumerate
调用来处理row
值。这是我的另一个建议:
如果您使用循环,使用另一个枚举和getattr
函数,您也可以使列复制代码更简单:
column_names = ["high0", "low1", "high1", "low2", "high2",
"low3", "high3", "low4", "high4", "low5",
"high5", "low6", "high6", "low7", "high7"]
# ...
for row, city in enumerate(cities, start=1):
for column, col_name in enumerate(column_names, start=1):
sheet.write(row, column, getattr(city, col_name))
编辑:进一步的改进可能是使city
实例可以直接迭代,因此您不需要使用getattr
跳过箍。这是一种粗略的方法:
class city: # note, if you're using Python 2, you should inherit from object
# other stuff
def __iter__(self):
return iter([self.high0, self.low1, self.high1, self.low2, self.high2,
self.low3, self.high3, self.low4, self.high4, self.low5,
self.high5, self.low6, self.high6, self.low7, self.high7])
更好的解决方案是取消命名属性,而是使用列表作为类中的基础数据结构。至少,如果你仍然需要能够使用属性语法,这有点复杂:
class city:
def __init__(city_name, link) :
self.name = city_name
self.url = link
self.data = [0] * 15
def _attr_index(self, name):
"""Translate an name into an integer index, or raise an exception"""
if name.startswith("high") and len(name) == 5:
n = int(name[-1])
if 0 <= n <= 7:
return n*2 # even indexes 0-14
if name.startswith("low") and len(name) == 4:
n = int(name[-1])
if 1 <= n <= 7:
return n*2 - 1 # odd indexes 1-13
raise ValueError()
def __getattr__(self, name):
try:
return self.data[self._attr_index(name)]
except ValueError:
return super().__getattr__(name) # should raise an AttributeError
def __setattr__(self, name, value):
try:
self.data[self._attr_index(name)] = value
except ValueError:
super().__setattr__(name, value) # will do a regular assignemnt
def __iter__(self):
return iter(self.data)
# other stuff
使用其中任何一个,脚本中的代码将变得非常简单:
for row, city in enumerate(cities, start=1):
for column, value in enumerate(city, start=1):
sheet.write(row, column, value)