Веб-скрейпинг с данными Wunderground, BeautifulSoup

Ладно, я тут в тупике. Для моего класса мы должны соскабливать данные с wunderground.com сайт. Мы продолжаем работать с проблемами (сообщения об ошибках), или код будет работать хорошо, но .txt-файл не будет содержать данных. Это довольно раздражает, потому что мне нужно это сделать! так вот мой код.

f = open('wunder-data1.txt', 'w')
for m in range(1, 13):
for d in range(1, 32):
    if (m == 2 and d > 28):
        break
    elif (m in [4, 6, 9, 11] and d > 30):
        break
    url = "http://www.wunderground.com/history/airport/KBUF/2009/" + str(m) + "/" + str(d) + "/DailyHistory.html"
    page = urllib2.urlopen(url)
    soup = BeautifulSoup(page, "html.parser")
    dayTemp = soup.find("span", text="Mean Temperature").parent.find_next_sibling("td").get_text(strip=True)
    if len(str(m)) < 2:
        mStamp = '0' + str(m)
    else:
        mStamp = str(m)
    if len(str(d)) < 2:
        dStamp = '0' +str(d)
    else:
        dStamp = str(d)
    timestamp = '2009' + mStamp +dStamp
    f.write(timestamp.encode('utf-8') + ',' + dayTemp + 'n')
    f.close()

Кроме того, извините, этот код, вероятно, не правильные отступы, как это в Python. Я в этом не силен.

UPDATE: кто-то ответил на вопрос ниже, и это сработало, но я понял, что вытягиваю неправильные данные (oops). Поэтому я положил это:

    import codecs
    import urllib2
    from bs4 import BeautifulSoup

    f = codecs.open('wunder-data2.txt', 'w', 'utf-8')

    for m in range(1, 13):
        for d in range(1, 32):
            if (m == 2 and d > 28):
                break
            elif (m in [4, 6, 9, 11] and d > 30):
                break

            url = "http://www.wunderground.com/history/airport/KBUF/2009/" + str(m) + "/" + str(d) + "/DailyHistory.html"
            page = urllib2.urlopen(url)
            soup = BeautifulSoup(page, "html.parser")

            dayTemp = soup.findAll(attrs={"class":"wx-value"})[5].span.string
            if len(str(m)) < 2:
                mStamp = '0' + str(m)
            else:
                mStamp = str(m)
            if len(str(d)) < 2:
                dStamp = '0' +str(d)
            else:
                dStamp = str(d)

            timestamp = '2009' + mStamp +dStamp

            f.write(timestamp.encode('utf-8') + ',' + dayTemp + 'n')

    f.close()

Так что я не уверен. То, что я пытаюсь сделать, это соскоб данных

1 ответ

  1. Я обнаружил следующие ошибки (и исправил их ниже) при попытке выполнить ваш код:

    1. Отступ вложенных циклов недопустим.
    2. Отсутствует импорт (строки в верхней части), но, возможно, вы просто исключили их из своей вставки.
    3. Попытка записи» utf-8 «закодированных строк в файл «ascii». Чтобы исправить это, я использовал codecsмодуль, чтобы открыть файл fкак «utf-8».
    4. Файл был закрыт внутри цикла, что означает, что после записи в него в первый раз, он будет закрыт, а затем следующая запись не будет выполнена (потому что он был закрыт). Я переместил линию, чтобы закрыть файл с внешней стороны петель.

    Теперь, насколько я могу сказать (без того, чтобы вы сказали нам, что вы на самом деле хотите, чтобы этот код сделал), он работает? По крайней мере, нет ошибок сразу появляются…

    import codecs
    import urllib2
    from bs4 import BeautifulSoup
    
    f = codecs.open('wunder-data1.txt', 'w', 'utf-8')
    
    for m in range(1, 13):
        for d in range(1, 32):
            if (m == 2 and d > 28):
                break
            elif (m in [4, 6, 9, 11] and d > 30):
                break
    
            url = "http://www.wunderground.com/history/airport/KBUF/2009/" + str(m) + "/" + str(d) + "/DailyHistory.html"
            page = urllib2.urlopen(url)
            soup = BeautifulSoup(page, "html.parser")
    
            dayTemp = soup.find("span", text="Mean Temperature").parent.find_next_sibling("td").get_text(strip=True)
    
            if len(str(m)) < 2:
                mStamp = '0' + str(m)
            else:
                mStamp = str(m)
            if len(str(d)) < 2:
                dStamp = '0' +str(d)
            else:
                dStamp = str(d)
    
            timestamp = '2009' + mStamp +dStamp
    
            f.write(timestamp.encode('utf-8') + ',' + dayTemp + '\n')
    
    f.close()
    

    Как показали комментарии к вашему вопросу, здесь есть другие области для улучшения, которые я не касался — я просто пытался получить код, который вы опубликовали, выполняя.