AttributeError: у объекта 'NoneType' нет атрибута 'strip' с Python WebCrawler - PullRequest
0 голосов
/ 03 августа 2011

Я пишу программу на Python для сканирования твиттера, используя комбинацию urllib2, обертки для python для API и BeautifulSoup.Однако, когда я запускаю свою программу, я получаю сообщение об ошибке следующего типа:

ray_krueger RafaelNadal

Traceback (most recent call last):
  File "C:\Users\Public\Documents\Columbia Job\Python Crawler\Twitter Crawler\crawlerversion9.py", line 78, in <module>
    crawl(start_follower, output, depth)
  File "C:\Users\Public\Documents\Columbia Job\Python Crawler\Twitter Crawler\crawlerversion9.py", line 74, in crawl
    crawl(y, output, in_depth - 1)
  File "C:\Users\Public\Documents\Columbia Job\Python Crawler\Twitter Crawler\crawlerversion9.py", line 74, in crawl
    crawl(y, output, in_depth - 1)
  File "C:\Users\Public\Documents\Columbia Job\Python Crawler\Twitter Crawler\crawlerversion9.py", line 64, in crawl
    request = urllib2.Request(new_url)
  File "C:\Python28\lib\urllib2.py", line 192, in __init__
    self.__original = unwrap(url)
  File "C:\Python28\lib\urllib.py", line 1038, in unwrap
    url = url.strip()
AttributeError: 'NoneType' object has no attribute 'strip'

Я совершенно незнаком с этим типом ошибки (новичок в python) ипоиск его в Интернете дал очень мало информации.Я также приложил свой код, но есть ли у вас какие-либо предложения?

Спасибо Снехиззы

import twitter
import urllib
import urllib2
import htmllib
from BeautifulSoup import BeautifulSoup
import re

start_follower = "NYTimeskrugman" 
depth = 3
output = open(r'C:\Python27\outputtest.txt', 'a') #better to use SQL database thanthis

api = twitter.Api()

#want to also begin entire crawl with some sort of authentication service 

def site(follower):
    followersite = "http://mobile.twitter.com/" + follower
    return followersite

def getPage(follower): 
    thisfollowersite = site(follower)
    request = urllib2.Request(thisfollowersite)
    response = urllib2.urlopen(request)
    return response

def getSoup(response): 
    html = response.read()
    soup = BeautifulSoup(html)
    return soup

def get_more_tweets(soup): 
    links = soup.findAll('a', {'href': True}, {id : 'more_link'})
    for link in links:
        b = link.renderContents()
        if str(b) == 'more':
            c = link['href']
            d = 'http://mobile.twitter.com' +c
            return d

def recordlinks(soup,output):
    tags = soup.findAll('div', {'class' : "list-tweet"})#to obtain tweet of a follower
    for tag in tags: 
        a = tag.renderContents()
        b = str (a)
        output.write(b)
        output.write('\n\n')

def checkforstamp(soup):
    times = nsoup.findAll('a', {'href': True}, {'class': 'status_link'})
    for time in times:
        stamp = time.renderContents()
        if str(stamp) == '3 months ago':
            return True

def crawl(follower, output, in_depth):
    if in_depth > 0:
        output.write(follower)
        a = getPage(follower)
        new_soup = getSoup(a)
        recordlinks(new_soup, output)
        currenttime = False 
        while currenttime == False:
            new_url = get_more_tweets(new_soup)
            request = urllib2.Request(new_url)
            response = urllib2.urlopen(request)
            new_soup = getSoup(response)
            recordlinks(new_soup, output)
            currenttime = checkforstamp(new_soup)
        users = api.GetFriends(follower)
        for u in users[0:5]:
            x = u.screen_name 
            y = str(x)
            print y
            crawl(y, output, in_depth - 1)
            output.write('\n\n')
        output.write('\n\n\n')

crawl(start_follower, output, depth)
print("Program done. Look at output file.")

Ответы [ 4 ]

1 голос
/ 03 августа 2011

AttributeError: объект 'NoneType' не имеет атрибута 'strip'

Это означает именно то, что написано: url.strip() требует сначала выяснить, что такое url.strip, то есть поиск атрибута strip в url. Это не удалось, потому что url является 'NoneType' object, то есть объектом с типом NoneType, то есть специальным объектом None.

Предположительно url должен был быть str, то есть текстовой строкой, поскольку они имеют атрибут strip.

Это произошло в File "C:\Python28\lib\urllib.py", то есть в модуле urllib. Это не ваш код, поэтому мы просматриваем трассировку исключений, пока не найдем что-то написанное: request = urllib2.Request(new_url). Мы можем только предполагать, что new_url, который мы передаем в модуль urllib2, в конечном итоге становится переменной url где-то в пределах urllib.

Так откуда взялась new_url? Мы ищем строку кода, о которой идет речь (обратите внимание, что в трассировке исключений есть номер строки), и мы видим, что непосредственно предыдущей строкой является new_url = get_more_tweets(new_soup), поэтому мы используем результат для get_more_tweets.

Анализ этой функции показывает, что она просматривает некоторые ссылки, пытается найти одну, помеченную «больше», и дает нам URL для первой такой ссылки, которую она находит. Случай, который мы не рассмотрели, это когда таких ссылок нет. В этом случае функция просто достигает конца и неявно возвращает None (именно так Python обрабатывает функции, которые достигают конца без явного возврата, поскольку в Python нет спецификации возвращаемого типа и поскольку значение всегда должно возвращаться) отсюда исходит это значение.

Предположительно, если нет ссылки «больше», то мы не должны пытаться перейти по ссылке вообще. Поэтому мы исправляем ошибку, явно проверяя это возвращаемое значение None и пропуская urllib2.Request в этом случае, так как нет ссылки для перехода.

Кстати, это значение None будет более идиоматическим значением "заполнителя" для еще не определенного currenttime, чем значение False, которое вы используете в настоящее время. Вы также можете подумать о том, чтобы быть более последовательным в разделении слов и подчеркиваний в именах переменных и методов, чтобы было легче читать. :)

0 голосов
/ 03 августа 2011

Когда вы делаете: request = urllib2.Request(new_url), new_url должна быть строкой, эта ошибка говорит, что это None.

Вы получаете значение new_url из функции get_more_tweets, поэтому оно где-то вернуло None.

def get_more_tweets(soup): 
    links = soup.findAll('a', {'href': True}, {id : 'more_link'})
    for link in links:
        b = link.renderContents()
        if str(b) == 'more':
            c = link['href']
            d = 'http://mobile.twitter.com' +c
            return d

Когда мы смотрим на этот код, функция возвращает только когда str(b)=="more" по какой-то ссылке, поэтому ваша проблема в том, «почему никогда не происходит str (b) ==« more »?».

0 голосов
/ 03 августа 2011

Вы передаете None вместо строки в urllib2.Request(). Глядя на код, это означает, что new_url иногда None. И, глядя на вашу get_more_tweets() функцию, которая является источником этой переменной, мы видим это:

def get_more_tweets(soup): 
    links = soup.findAll('a', {'href': True}, {id : 'more_link'})
    for link in links:
        b = link.renderContents()
        if str(b) == 'more':
            c = link['href']
            d = 'http://mobile.twitter.com' +c
            return d

Эта функция возвращает значение, только если b равно "more", потому что ваш оператор return имеет отступ под if. Если оно равно любому другому значению, никакое значение (т.е. None) не возвращается.

Вам необходимо либо всегда возвращать действительный URL-адрес, либо проверить возвращаемое значение None, прежде чем передавать его на urllib2.Request().

0 голосов
/ 03 августа 2011

Когда вы делаете

request = urllib2.Request(new_url)

в crawl(), new_url равно None.Когда вы получаете new_url от get_more_tweets(new_soup), это означает, что get_more_tweets() возвращает None.

Это означает, что return d никогда не достигается, что означает, что либо str(b) == 'more' никогда не было верноили soup.findAll() не вернул никаких ссылок, поэтому for link in links ничего не делает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...