Python爬虫Csdn系列III

来源:互联网 发布:php中的正则表达式 编辑:程序博客网 时间:2024/05/29 02:33

Python爬虫Csdn系列III



By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢。


说明:


在上一篇博客中,我们已经能够获取一个用户所有文章的链接了,那么这一节自然就是要将这些博客下载下来咯。

分析:


有了链接下载文章自然是不难。但是,获取的数据该怎么处理?每一篇文章都带有格式换行这些信息,自然,我们存储它们也是要存储其对应的html格式的数据的(注意,我们编辑的带有格式的博客或者其他文本都是以html代码格式存储的)。如何存?使用数据库,每篇文章字数都挺大的,没必要用数据库,还是存储文件更方便。

这里我将下载的每篇博客都取出文章的div部分,然后给这个部分添加必要的html头部及其尾部,将其封装成一个完整的html文本,最后再保存成html格式的文件。这里要注意的就是在html中一定要添加<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />这句话,否则显示的会是乱码。

核心代码在前两篇文章已经提到了,难度也不是很大。


代码:

#-*- coding:utf-8 -*-import sysimport osimport codecsimport urllibimport urllib2import cookielibimport MySQLdbimport refrom bs4 import BeautifulSoupfrom article import CsdnArticlereload(sys)sys.setdefaultencoding('utf-8')class CsdnCrawler(object):def __init__(self, author = 'whiterbear'):self.author = authorself.domain = 'http://blog.csdn.net/'self.headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36'}self.articles = []#给定url,得到所有的文章listsdef getArticleLists(self, url= None):req = urllib2.Request(url, headers=self.headers)response = urllib2.urlopen(req)soup = BeautifulSoup(''.join(response.read()))listitem =  soup.find(id='article_list').find_all(attrs={'class':r'list_item article_item'})href_regex = r'href="(.*?)"'for i,item in enumerate(listitem):enitem = item.find(attrs={'class':'link_title'}).contents[0].contents[0]href = re.search(href_regex,str(item.find(attrs={'class':'link_title'}).contents[0])).group(1)art = CsdnArticle()art.author = self.authorart.title = enitem.lstrip()art.href = (self.domain + href[1:]).lstrip()self.articles.append(art)def getPageLists(self, url= None):url = url if url else 'http://blog.csdn.net/%s?viewmode=list'%self.authorreq = urllib2.Request(url, headers=self.headers)response = urllib2.urlopen(req)soup = BeautifulSoup(''.join(response.read()))num_regex = '[1-9]\d*'pagelist = soup.find(id='papelist')self.getArticleLists(url)if pagelist:pagenum = int(re.findall(num_regex, pagelist.contents[1].contents[0])[1])for i in range(2, pagenum + 1):self.getArticleLists(self.domain + self.author + '/article/list/%s'%i)def getAllArticles(self):#我们创建一个该作者的文件夹来存放作者的文章if not os.path.exists(self.author):os.mkdir(self.author)for subarticle in self.articles:articleurl = subarticle.href#依次打开每一篇文章并下载req = urllib2.Request(articleurl, headers=self.headers)response = urllib2.urlopen(req)soup = BeautifulSoup(''.join(response.read()))article_content = soup.find(id='article_content')title = subarticle.title.rstrip().encode('utf-8')#将提取的内容封装成html格式的字符串article = u'<html><head><title>%s</title><meta http-equiv="Content-Type" \content="text/html; charset=utf-8" /></head><body>%s</body></html>' % (title, article_content)fobj = codecs.open(u'%s/%s.htm'%(self.author, title),'w','utf-8')fobj.writelines(article.encode('utf-8'))fobj.close()def main():csdn = CsdnCrawler(author='whiterbear')#'pongba',可以将填入你想下载的博主的博客csdn.getPageLists()csdn.getAllArticles()if __name__ == '__main__':main()


结果:


生成了该博主命名的文件夹,文件夹中包含该博主的所有文章。如下图:



随便打开一个文章,显示的效果是这样的:(显示的效果很赞。)



感悟:


1> 中文编码问题。虽然已经了解了几种编码问题的解决方式,但是还是常常被这个问题给卡住。

2> 保持代码的正交性。虽然我还没做过大项目,但是已经能够感受到,如果两个模块的正交性提高,即一个模块的改动并不会影响到另一个模块的正常运行。这样子能够迫使你去思考一种清晰的框架,而不会写了一团糟的代码。

3> 常见的错觉,总觉得这个很简单啊,今天就可以做完啊,结果总是遇到这样那样的问题,还是缺少经验。

4> 其他:保持代码的整洁,尝试迭代,从小的代码开始一点点往上累计新的代码,时刻保持两个版本(其中一个含有大量输出来帮你确定每一步发生了什么)。

 

下个系列可能就要开始做微博的爬虫了,会涉及到相关的数据处理和分析,希望能顺利点。


0 0
原创粉丝点击