接下来,我需要把采集的信息入库,说白了,就是把我自己蜘蛛的信息利用django的ORM存到django连接的数据库里面,方便以后再用Django读取用于做站。
入库的方法太多了,这里随便写一种,就是在web app里面建立一个spider.py, 里面定义两个蜘蛛,继承之前自己写的蜘蛛,再添加入库方法。
vim ~/python_spider/web/spider.py
代码如下:
# -*- coding: utf-8 -*-
from sfspider import spider
from web.models import Answer, Question, Tag
class 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, created
class 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:微信, 分页:3
KeyboardInterrupt # 用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
[, , , ]