繁体   English   中英

AttributeError:“ NoneType”对象在Python WebCrawler中没有属性“ strip”

[英]AttributeError: 'NoneType' object has no attribute 'strip' with Python WebCrawler

我正在编写一个python程序,使用urllib2,api的python twitter包装器和BeautifulSoup的组合来爬网Twitter。 但是,当我运行程序时,出现以下类型的错误:

ray_krueger拉斐尔·纳达尔

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来说是新的),在线搜索它产生的信息很少。 我也附上了我的代码,但是您有什么建议吗?

Thanx Snehizzy

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.")

AttributeError:“ NoneType”对象没有属性“ strip”

这意味着它的含义: url.strip()首先需要弄清楚url.strip是什么,即查找urlstrip属性。 失败是因为url是一个'NoneType' object ,即类型为NoneType的对象,即特殊对象None

大概url应该是str ,即文本字符串,因为它们确实具有strip属性。

这发生在File "C:\\Python28\\lib\\urllib.py" (即urllib模块)内。 那不是您的代码,因此我们向后浏览异常跟踪,直到找到我们编写的内容: request = urllib2.Request(new_url) 我们只能假定传递给urllib2模块的new_url最终成为urllib某处的url变量。

那么new_url是从哪里来的呢? 我们查找有问题的代码行(请注意,异常回溯中有一个行号),并且我们看到紧接的前一行是new_url = get_more_tweets(new_soup) ,因此我们将结果用于get_more_tweets

对该功能的分析表明,它搜索某些链接,尝试找到一个标记为“更多”的链接,并为我们提供它找到的第一个此类链接的URL。 我们没有考虑的情况是没有这样的链接。 在这种情况下,函数仅到达末尾,并隐式返回None(这是Python处理到达末尾的函数而没有显式返回的方式,因为Python中没有返回类型的规范,并且必须始终返回值) ,这就是价值的来源。

大概,如果没有“更多”链接,那么我们根本不应该尝试遵循该链接。 因此,我们通过显式检查此None返回值并在这种情况下跳过urllib2.Request来纠正错误,因为没有可链接的内容。

顺便说一句,这None值将是对还未确定的更地道的“占位符”值currenttimeFalse ,你正在使用的价值。 您可能还会考虑在变量和方法名称中用下划线分隔单词以使内容更易于阅读时保持一致。 :)

当你做

request = urllib2.Request(new_url)

crawl()new_urlNone 当您从get_more_tweets(new_soup)获取new_url ,这意味着get_more_tweets()返回None

这意味着永远不会到达return d ,这意味着str(b) == 'more'从来都不是真的,或者soup.findAll()没有返回任何链接,因此for link in links没有任何作用。

当您执行以下操作时: request = urllib2.Request(new_url)new_url应该是字符串,此错误表明它为None

您可以从get_more_tweets函数获取new_url的值,因此它在某处返回了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”?”。

您正在将None而不是字符串传递给urllib2.Request() 查看代码,这意味着new_url有时为None 并查看您的get_more_tweets()函数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,或者需要在将其传递给urllib2.Request()之前检查None返回值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM