Python 爬虫爬取指定博客的所有文章
自上一篇文章ZStory:UsingDjangowithGAEPython后台抓取多个网站的页面全文后,大体的进度如下:
1.增加了Cron:用来告诉程序每隔30分钟让一个task醒来,跑到指定的那几个博客上去爬取最新的更新
2.用google的Datastore来存贮每次爬虫爬下来的内容。。只存贮新的内容。。
就像上次说的那样,这样以来性能有了大幅度的提高:原来的每次请求后,爬虫才被唤醒所以要花大约17秒的时间才能从后台输出到前台而现在只需要2秒不到
3.对爬虫进行了优化
1.Cron.yaml来安排每个程序醒来的时间
经过翻文档,问问题终于弄明白google的cron的工作原理--实际上只是google每隔指定的时间虚拟地访问一个我们自己指定的url…
因此在Django下,根本不需要写一个纯的python程序一定不要写:
if__name__=="__main__":
只需要自己配置一个url放在views.py里:
defupdatePostsDB(request): #deleteAll() SiteInfos=[] SiteInfo={} SiteInfo['PostSite']="L2ZStory" SiteInfo['feedurl']="feed://l2zstory.wordpress.com/feed/" SiteInfo['blog_type']="wordpress" SiteInfos.append(SiteInfo) SiteInfo={} SiteInfo['PostSite']="YukiLife" SiteInfo['feedurl']="feed://blog.sina.com.cn/rss/1583902832.xml" SiteInfo['blog_type']="sina" SiteInfos.append(SiteInfo) SiteInfo={} SiteInfo['PostSite']="ZLife" SiteInfo['feedurl']="feed://ireallife.wordpress.com/feed/" SiteInfo['blog_type']="wordpress" SiteInfos.append(SiteInfo) SiteInfo={} SiteInfo['PostSite']="ZLife_Sina" SiteInfo['feedurl']="feed://blog.sina.com.cn/rss/1650910587.xml" SiteInfo['blog_type']="sina" SiteInfos.append(SiteInfo) try: forsiteinSiteInfos: feedurl=site['feedurl'] blog_type=site['blog_type'] PostSite=site['PostSite'] PostInfos=getPostInfosFromWeb(feedurl,blog_type) recordToDB(PostSite,PostInfos) Msg="CronJobDone..." exceptException,e: Msg=str(e) returnHttpResponse(Msg)
cron.yaml要放在跟app.yaml同一个级别上:
cron:
-description:retrievenewestposts
url:/task_updatePosts/
schedule:every30minutes
在url.py里只要指向这个把task_updatePostsDB指向url就好了
调试这个cron的过程可以用惨烈来形容。。。在stackoverflow上有很多很多人在问为什么自己的cron不能工作。。。我一开始也是满头是汗,找不着头脑。。。最后侥幸弄好了,大体步骤也是空泛的很。。但是很朴实:
首先,一定要确保自己的程序没有什么syntaxerror….然后可以自己试着手动访问一下那个url如果cron正常的话,这个时候任务应该已经被执行了最后实在不行的话多看看log…
2.Datastore的配置和利用--UsingDatastorewithDjango
我的需求在这里很简单--没有join…所以我就直接用了最简陋的django-helper..
这个models.py是个重点:
fromappengine_django.modelsimportBaseModel fromgoogle.appengine.extimportdb
classPostsDB(BaseModel): link=db.LinkProperty() title=db.StringProperty() author=db.StringProperty() date=db.DateTimeProperty() description=db.TextProperty() postSite=db.StringProperty()