2016-07-27 83 views
0

正如前面的問題所述,我使用美麗的湯與python從網站檢索天氣數據。使用BeautifulSoup循環瀏覽HTML標籤

下面是該網站的樣子:

<channel> 
<title>2 Hour Forecast</title> 
<source>Meteorological Services Singapore</source> 
<description>2 Hour Forecast</description> 
<item> 
<title>Nowcast Table</title> 
<category>Singapore Weather Conditions</category> 
<forecastIssue date="18-07-2016" time="03:30 PM"/> 
<validTime>3.30 pm to 5.30 pm</validTime> 
<weatherForecast> 
<area forecast="TL" lat="1.37500000" lon="103.83900000" name="Ang Mo Kio"/> 
<area forecast="SH" lat="1.32100000" lon="103.92400000" name="Bedok"/> 
<area forecast="TL" lat="1.35077200" lon="103.83900000" name="Bishan"/> 
<area forecast="CL" lat="1.30400000" lon="103.70100000" name="Boon Lay"/> 
<area forecast="CL" lat="1.35300000" lon="103.75400000" name="Bukit Batok"/> 
<area forecast="CL" lat="1.27700000" lon="103.81900000" name="Bukit Merah"/>` 
.. 
.. 
<area forecast="PC" lat="1.41800000" lon="103.83900000" name="Yishun"/> 
<channel> 

我設法找回我需要使用這些代碼的信息:

import requests 
from bs4 import BeautifulSoup 
import urllib3 
import csv 
import sys 
import json 

#getting the Validtime 

area_attrs_li = [] 

r = requests.get('http://www.nea.gov.sg/api/WebAPI/?  
dataset=2hr_nowcast&keyref=781CF461BB6606AD907750DFD1D07667C6E7C5141804F45D') 
soup = BeautifulSoup(r.content, "xml") 
time = soup.find('validTime').string 
print "validTime: " + time 

#getting the date 

for currentdate in soup.find_all('item'): 
element = currentdate.find('forecastIssue') 
print "date: " + element['date'] 

#getting the time 

for currentdate in soup.find_all('item'): 
element = currentdate.find('forecastIssue') 
print "time: " + element['time'] 

#print area 

for area in soup.select('area'): 
area_attrs_li.append(area) 
print area 

#print area name 

areas = soup.select('area') 
for data in areas: 
    name = (data.get('name')) 
    print name 

f = open("C:\\scripts\\testing\\testingnea.csv" , 'wt') 

try: 
    for area in area_attrs_li: 
    #print str(area) + "\n" 
    writer = csv.writer(f) 
    writer.writerow((time, element['date'], element['time'], area, name)) 

finally: 
    f.close() 

print open("C:/scripts/testing/testingnea.csv", 'rt').read() 

我設法在一個CSV數據,但是當我運行這部分代碼:

#print area name 

areas = soup.select('area') 
for data in areas: 
    name = (data.get('name')) 
    print name 

這是結果:

This is what I got

很顯然,我的迴路不工作,因爲它保持了一遍又一遍打印的最後一個記錄的最後一個領域。

編輯:我想從數據列表中的區域循環:

for area in area_attrs_li: 
    name = (area.get('name')) 
    print name 

但是,它仍然沒有循環。

我不知道在哪裏的代碼出錯:/

回答

1

這是因爲當你寫,你是指循環的最後一個實例,試試這個:

writer.writerow((time, element['date'], element['time'], area, area['name'])) 
+0

我不明白你的意思,「當你正在寫作時,你指的是循環的最後一個實例」對不起! :/ – plzhelpmi

+0

當你寫作時(writer.writerow((time,element ['date'],element ['time'],area,name))),name變量在區域名稱循環後保存最後一個值,可以事實上刪除>> area_attrs_li中的區域: name =(area.get('name')) 打印名稱,雖然它也可以工作,但實踐中您可以嘗試刪除該循環也可以 –

+0

我可以問爲什麼當它我把它稱爲循環的最後一個實例的名稱,但是當我放置區域時,它工作得很好嗎? – plzhelpmi

1

的問題是在該行:writer.writerow((time, element['date'], element['time'], area, name)),在name永遠不會改變。

辦法解決它:

try: 
    for index, area in enumerate(area_attrs_li): 
     # print str(area) + "\n" 
     writer = csv.writer(f) 
     writer.writerow((time, element['date'], element['time'], area, areas[index].get('name'))) 
finally: 
    f.close() 
+0

你是什麼意思的名字永遠不會改變的意思嗎? :x – plzhelpmi

1

你只得到了循環後名稱變量中的一個值。你需要有一個列表。試試這個

areas = soup.select('area') 
name=[] 
for data in areas: 
    name.append(data.get('name')) 
    print name 
l=len(name) 

,並嘗試終於

i=0 
try: 
    for area in area_attrs_li: 
     writer = csv.writer(f) 
     writer.writerow((time, element['date'], element['time'], area, name[i])) 
     i=i+1 
+0

噢,所以我必須創建一個列表,就像我創建一個存儲區域一樣? – plzhelpmi

+0

是的,你是一次又一次地寫同一個值的變量,這就是爲什麼你總是得到最後一次輸入的原因。 –