多语言展示
当前在线:247今日阅读:75今日分享:44

Python 爬虫建站入门手记(3):采集入库

上回,我已经大概把爬虫写出来了。我写了一个内容爬虫,一个爬取tag里面内容链接的爬虫其实还差一个,就是收集一共有哪些tag的爬虫。但是这里先不说这个问题,因为我上次忘了 这次又不想弄。。
1 定义数据库(or model or schema)

为了入库,我需要在Django定义一个数据库的结构。(不说nosql和mongodb(也是一个nosql但是很像关系型)的事)还记得那个名叫web的app么,里面有个叫models.py的文件,我现在就来编辑它。vim ~/python_spider/web/models.py内容如下:# -*- coding: utf-8 -*-from django.db import models# Create your models here.class Tag(models.Model):    title = models.CharField(max_length=30)    def __unicode__(self):        return self.titleclass Question(models.Model):    title = models.CharField(max_length=255)    content = models.TextField()    tags = models.ManyToManyField(Tag, related_name='questions')    sf_id = models.CharField(max_length=16, default='0') # 加上这个可以记住问题在sf的位置,方便以后更新或者其他操作    update_date = models.DateTimeField(auto_now=True)    def __unicode__(self):        return self.titleclass Answer(models.Model):    question = models.ForeignKey(Question, related_name='answers')    content = models.TextField()    def __unicode__(self):        return 'To question %s' % self.question.title都很直白,关于各个field可以看看 Django 的文档。然后,我需要告诉我的python_spider项目,在运行的时候加载web这个app(项目不会自动加载里面的app)。vim ~/python_spider/python_spider/settings.py在INSTALLED_APPS里面加入web:INSTALLED_APPS = (    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'web',)下面,就可以用django自动生成数据库schema了cd ~/python_spiderpython manage.py makemigrationspython manage.py migrate现在,我~/python_spider目录就产生了一个db.sqlite3文件,这是我的数据库。把玩一番我的模型>>> from web.models import Answer, Question, Tag>>> tag = Tag()>>> tag.title = u'测试标签'>>> tag.save()>>> tag>>> question = Question(title=u'测试提问', content=u'提问内容')>>> question.save()>>> question.tags.add(tag)>>> question.save()>>> answer = Answer(content=u'回答内容', question=question)>>> answer.save()>>> tag.questions.all() # 根据tag找question[]>>> question.tags.all() # 获取question的tags[]>>> question.answers.all() # 获取问题的答案[]以上操作结果正常,说明定义的models是可用的。END

2 入库

接下来,我需要把采集的信息入库,说白了,就是把我自己蜘蛛的信息利用django的ORM存到django连接的数据库里面,方便以后再用Django读取用于做站。入库的方法太多了,这里随便写一种,就是在web app里面建立一个spider.py, 里面定义两个蜘蛛,继承之前自己写的蜘蛛,再添加入库方法。vim ~/python_spider/web/spider.py代码如下:# -*- coding: utf-8 -*-from sfspider import spiderfrom web.models import Answer, Question, Tagclass ContentSpider(spider.SegmentfaultQuestionSpider):    def save(self): # 添加save()方法        sf_id = self.url.split('/')[-1] # 1        tags = [Tag.objects.get_or_create(title=tag_title)[0] for tag_title in self.tags] # 2        question, created = Question.objects.get_or_create(            sf_id=sf_id,            defaults={'title':self.title, 'content':self.content}        ) # 3        question.tags.add(*tags) # 4        question.save()        for answer in self.answers:            Answer.objects.get_or_create(content=answer, question=question)        return question, createdclass TagSpider(spider.SegmentfaultTagSpider):    def crawl(self): # 采集当前分页        sf_ids = [url.split('/')[-1] for url in self.questions]        for sf_id in sf_ids:            question, created = ContentSpider(sf_id).save()    def crawl_all_pages(self):        while True:            print u'正在抓取TAG:%s, 分页:%s' % (self.tag_name, self.page) # 5            self.crawl()            if not self.has_next_page:                break            else:                self.next_page()这个地方写得很笨,之前该在SegmentfaultQuestionSpider加上这个属性。创建或者获取该提问的tags创建或者获取提问,采用sf_id来避免重复把tags都添加到提问,这里用*是因为这个方法原本的参数是(tag1, tag2, tag3)。但是我们的tags是个列表测试的时候方便看看进度然后,测试下我们的入库脚本全选复制放进笔记python manage.py shell>>> from web.spider import TagSpider>>> t = TagSpider(u'微信')>>> t.crawl_all_pages()正在抓取TAG:微信, 分页:1正在抓取TAG:微信, 分页:2正在抓取TAG:微信, 分页:3KeyboardInterrupt # 用control-c中断运行,测试一下就行:)>>> from web.models import Tag, Question>>> Question.objects.all()[, , , , , , , , , , , , , , , , , , , , '...(remaining elements truncated)...']>>> Question.objects.get(pk=5).tags.all() # 数据库中id=5的question的tags[, , , ]END

3 设置django.contrib.admin来查看和编辑内容

为了更直观的观察我采集的数据,我可以利用django自带的admin编辑文件vim ~/python_spider/web/admin.pyfrom django.contrib import adminfrom web.models import Tag, Question, Answeradmin.site.register(Tag)admin.site.register(Question)admin.site.register(Answer)然后创建超级用户python manage.py createsuperuser # 根据提示创建启动测试服务器python manage.py runserver 0.0.0.0:80 # 我这是在runabove上,本地直接manage.py runserver然后,我访问http://192.99.71.91/admin/登录刚刚创建的账号,就能对内容进行查看和编辑了END

推荐信息