2014-10-03 2 views
0

Я использую следующий код (слегка модифицированный из раннего примера «Визуализировать этот» Натан Яу, чтобы очистить метеорологические данные с сайта WUnderGround. Как вы можете видеть, python захватывает числовые данные из элемента с именем класса «wx-data».Как использовать beautifulsoup, когда элемент HTML не имеет имени класса?

Однако я также хотел бы получить среднюю влажность от DailyHistory.htmml. Проблема в том, что не все элементы «span» имеют имя класса, что имеет место для ячейки средней влажности. Как я могу выбрать эту конкретную ячейку с помощью BeautifulSoup и кода ниже?

(Вот пример страницы, которая Царапины - ударилась в режим разработчика и поиск «WX-данных», чтобы увидеть элемент «пролет» на который ссылается:

http://www.wunderground.com/history/airport/LAX/2002/1/1/DailyHistory.html)

import urllib2 
from BeautifulSoup import BeautifulSoup 

year = 2004  


#create comma-delim file 

f = open(str(year) + '_LAXwunder_data.txt','w') 

#iterate through month and day 
for m in range(1,13): 
    for d in range (1,32): 

     #Chk if already gone through month 
     if (m == 2 and d > 28): 
      break 
     elif (m in [4,6,9,11]) and d > 30: 
      break 

     # open wug url 
     timestamp = str(year)+'0'+str(m)+'0'+str(d) 
     print 'Getting data for ' + timestamp 
     url = 'http://www.wunderground.com/history/airport/LAX/'+str(year) + '/' + str(m) + '/' + str(d) + '/DailyHistory.html' 
     page = urllib2.urlopen(url) 

     #Get temp from page 
     soup = BeautifulSoup(page) 
     #dayTemp = soup.body.wx-data.b.string 
     dayTemp = soup.findAll(attrs = {'class':'wx-data'})[5].span.string 

     #Format month for timestamp 
     if len(str(m)) < 2: 
      mStamp = '0' + str(m) 
     else: 
      mStamp = str(m) 
     #Format day for timestamp 
     if len(str(d)) < 2: 
      dStamp = '0' + str(d) 
     else: 
      dStamp = str(d) 

     #Build timestamp 
     timestamp = str(year)+ mStamp + dStamp 

     #Wrtie timestamp and temp to file 
     f.write(timestamp + ',' + dayTemp +'\n') 

#done - close 
f.close() 
+0

из любопытства, почему вы используете BeautifulSoup версии 3, а не 4 версии? Вы хотите 'pip install beautifulsoup4' и использовать' from bs4 import BeautifulSoup' вместо этого. –

+0

Наверное, потому что книга с 2011 года :) – d8aninja

ответ

1

Вы можете искать ячейку, содержащую текст, а затем двигаться вверх и к следующей ячейке:

humidity = soup.find(text='Average Humidity') 
next_cell = humidity.find_parent('td').find_next_sibling('td') 
humidity_value = next_cell.string 

Я использую Beautifu lSoup версия 4 здесь, а не 3; вы действительно хотите обновиться, поскольку версия 3 была законсервирована 2 года назад.

BeautifulSoup 3 может сделать этот конкретный трюк; используйте findParent() и findNextSibling(), а не там.

Демо:

>>> import requests 
>>> from bs4 import BeautifulSoup 
>>> response = requests.get('http://www.wunderground.com/history/airport/LAX/2002/1/1/DailyHistory.html') 
>>> soup = BeautifulSoup(response.content) 
>>> humidity = soup.find(text='Average Humidity') 
>>> next_cell = humidity.find_parent('td').find_next_sibling('td') 
>>> next_cell.string 
u'88' 
0

Большое спасибо @Martijn_Pieters за помощь делает этот окончательный сценарий:

import requests 
import urllib2 
from bs4 import BeautifulSoup 

year = 2003 

#create comma-delim file 
f = open(str(year) + '_LAXwunder_data.txt','w') 
#change the year here, ->run 


#iterate through month and day 
for m in range(1,13): 
    for d in range(1,32): #could step 5 days using range(1,32,2) 

     #Chk if already gone through month 
     if (m == 2 and d > 28): 
      break 
     elif (m in [4,6,9,11]) and d > 30: 
      break 

     # open wug url 
     timestamp = str(year)+'.'+str(m)+'.'+str(d) 
     print 'Getting data for ' + timestamp 
     url = 'http://www.wunderground.com/history/airport/LAX/'+str(year) + '/' + str(m) + '/' + str(d) + '/DailyHistory.html' 
     page = urllib2.urlopen(url) 
     #Get temp from page 
     soup = BeautifulSoup(page) 
     #dayTemp = soup.body.wx-data.b.string 
     dayTemp = soup.findAll(attrs = {'class':'wx-data'})[5].span.string 
      humidity = soup.find(text='Average Humidity') 
       next_cell = humidity.find_parent('td').find_next_sibling('td') 
       avg_humidity = next_cell.string 

     #Format month for timestamp 
     if len(str(m)) < 2: 
      mStamp = '0' + str(m) 
     else: 
      mStamp = str(m) 
     #Format day for timestamp 
     if len(str(d)) < 2: 
      dStamp = '0' + str(d) 
     else: 
      dStamp = str(d) 

     #Build timestamp 
     timestamp = str(year)+ mStamp + dStamp 

     #Wrtie timestamp and temp to file 
     f.write(timestamp + ',' + dayTemp + ',' + avg_humidity + '\n') 
     print dayTemp, avg_humidity 

#done - close 
f.close() 
+0

Не знаете, как еще пометить вас, @Martijn Pieters, но еще раз спасибо! – d8aninja