为了账号安全,请及时绑定邮箱和手机立即绑定

TypeError: 'NoneType' object is not iterable 怎么解决啊?

#coding:utf-8
from baike_spider import url_manager, html_downloader, html_parser,\
    html_outputer




class SpiderMain(object):
    def __init__(self):    #这些模块我们需要在各个函数中进行初始化
        self.urls=url_manager.UrlManager()  #url管理器
        self.downloader=html_downloader.HtmlDownloader() #html下载器
        self.parser=html_parser.HtmlParser()  #html解析器
        self.outputer=html_outputer.HtmlOutputer()  #输出器
        
    #爬虫的调度程序
    def craw(self, root_url):
        count=1
        self.urls.add_new_url(root_url)  #将入口url添加到管理器,这时url管理器中就有待爬取的url了
        while self.urls.has_new_url():  #循环:判断url管理器中是否有待爬取的url,即'has_new_url'为True或者False
            #try:
            new_url=self.urls.get_new_url() #url管理器中有待爬取的url,通过get_new_url获取一个待爬取的url
            print 'craw %d : %s'%(count,new_url)  #打印正在打印第几个url
            html_cont=self.downloader.download(new_url) #获取到一个待爬取的url后,启动下载器下载这个页面,结果储存在html_cont
            new_urls,new_data=self.parser.parse(new_url,html_cont) #24行:下载好的页面,调用parser解析器来解析这个页面,得到新的url列表(new_urls)和新的数据(new_data),解析器传入两个参数,当前爬取的url(new_url),以及下载好的页面数据(html_cont)
            self.urls.add_new_urls(new_urls)  #解析得到新的url(new_urls),添加到url管理器
            self.outputer.collect_data(new_data) #收集数据(new_data)
            
            if count==1000:
                break
            count+=1
            
            #except:           #遇到异常情况的处理(某个url无法访问
                #print 'craw failed'
                
        self.outputer.output_html()
    
    


#首先,编写main函数
if __name__=='__main__':
    root_url='http://baike.baidu.com/item/Python'  #设置入口url
    obj_spider=SpiderMain()   #创建实例,SpiderMain为类
    obj_spider.craw(root_url) #调用spider的craw方法,来启动爬虫
#coding:utf-8

#在每个模块中创建主程序所需的class
class UrlManager(object):
    def __init__(self):
        self.new_urls=set()  #新的和已经爬取过的url全部储存在 set()中
        self.old_urls=set()
    
    #向管理器中添加一个新的url
    def add_new_url(self,url):  #(利用这个方法.使self.new_urls中增加一个新的待爬取url)
        if url is None:
            return  #不进行添加
        if url not in self.new_urls and url not in self.old_urls:
            self.new_urls.add(url)
    
    #向管理器中添加批量新的url
    def add_new_urls(self,urls):   #new_urls为网页解析器解析得到的新的待爬取url列表
        if urls is None or len(urls)==0:  #如果这个urls列表长度为空或者为None
            return  #不进行添加
        for url in urls:
            self.add_new_url(url)   ##注意一下

    
    #判断管理器中是否有待爬取的url
    def has_new_url(self):        #has_new_url 用于spider_main中while语句的判断
        return len(self.new_urls) !=0   #如果长度不为0,就有待爬取的url
            
        

    #从url管理器中获取一个新的待爬取的url
    def get_new_url(self):
        new_url=self.new_urls.pop()  #从列表中获取一个url,并移除这个url
        self.old_urls.add(new_url)
        return new_url  #返回的new_url用于spider_main中的get_new_url
#coding:utf-8
import urllib2


#在每个模块中创建主程序所需的class
class HtmlDownloader(object):
    
    
    def download(self,url):
        if url is None:
            return None
        response=urllib2.urlopen(url)  #爬百度百科用的的为最简单的urllib2代码,没有cookie和代理的考虑
        if response.getcode() !=200:
            return None
        print response.read()
#coding:utf-8
from bs4 import BeautifulSoup
import re
import urlparse


#在每个模块中创建主程序所需的class
class HtmlParser(object):
    
    
    def _get_new_urls(self, page_url, soup):   #page_url是什么? page_url是主程序spider_main中给定的参数new_url.
        new_urls=set()
        #/item/123
        links=soup.find_all('a',href=re.compile(r'/item/'))  #compile(r"/item/\d+\\"))  #'\\',前一个\用来取消后一个\的转义功能
        for link in links:
            new_url=link['href']
            new_full_url=urlparse.urljoin(page_url,new_url) #将new_url按照page_url的格式,生成一个全新的url
            new_urls.add(new_full_url)
        return new_urls
    
    def _get_new_data(self, page_url, soup):
        res_data={}
        
        #url
        res_data['url']=page_url
        
        #<dd class="lemmaWgt-lemmaTitle-title">  <h1>Python</h1>
        title_node=soup.find('dd',class_="lemmaWgt-lemmaTitle-title").find('h1')
        res_data['title']=title_node.get_text()  #原先写错成get_txt()

        #<div class="lemma-summary" label-module="lemmaSummary">
        summary_node=soup.find('div',class_="lemma-summary")
        res_data['summary']=summary_node.get_text()
        
        return res_data
    
    
    def parse(self,page_url,html_cont):   #其中,(page_url,html_cont)就是 spider_main中第24行输入的参数 (new_url,html_cont)
        if page_url is None or html_cont is None:
            return

        soup=BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')
        new_urls=self._get_new_urls(page_url,soup)  #创建self._get_new_urls本地方法,这个方法主要是为了find_all所有相关网页url,并补全url,输出到new_urls这个列表当中,给spider_main使用
        new_data=self._get_new_data(page_url,soup)  #创建self._get_new_data
        return new_urls,new_data
#coding:utf-8


#在每个模块中创建主程序所需的class
class HtmlOutputer(object):
    def __init__(self):
        self.datas=[]
    
    def collect_data(self,data):
        if data is None:
            return
        self.datas.append(data)

    
    def output_html(self,data):
        fout=open('output.html','w')
        
        fout.write("<html>")
        fout.write("<body>")
        fout.write("<table>")
        
        #ascii
        for data in self.datas:
            fout.write("<tr>")
            fout.write("<td>%s</td>"% data['url'])
            fout.write("<td>%s</td>"% data['title'].encode('utf-8'))
            fout.write("<td>%s</td>"% data['summary'].encode('utf-8'))
            fout.write("</tr>")
        
        fout.write("</table>")
        fout.write("</body>")
        fout.write("</html>")
        
        
        fout.close()

http://img1.sycdn.imooc.com//5a4e150200019c0013660746.jpg

按照评论分享的代码重新改了几个地方,但依然出现这个错误.不知道错在哪里了,代码以上.

正在回答

1 回答

页面  html_downloader.py

15行   print response.read()   更改为  return response.read()

0 回复 有任何疑惑可以回复我~
#1

LNYIE 提问者

可以了 谢谢
2018-01-05 回复 有任何疑惑可以回复我~
#2

LNYIE 提问者

弱弱的问一句,为什么print不行呢
2018-01-05 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
Python开发简单爬虫
  • 参与学习       227670    人
  • 解答问题       1219    个

本教程带您解开python爬虫这门神奇技术的面纱

进入课程

TypeError: 'NoneType' object is not iterable 怎么解决啊?

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信