(1)Python笔记:抓取CSDN博文

来源:互联网 发布:贵州 大数据大诚信 编辑:程序博客网 时间:2024/06/16 19:31

刚开始学习Python,之前花了一个下午过了一遍基础知识,可能是因为有C,C++基础,又正在做Java开发的原因吧,感觉很容易理解,整体语法也很简洁,确实越写越舒服,就是不需要;号结尾可能还要点时间习惯吧_ (:3」∠*)_。
入门书籍用的是《Python编程:从入门到实践》,其他初学童鞋也可以借鉴下,书写的不错,很简洁,算是对Python有了一些大体上的认知,实际果然还是需要动手做些东西才行。
其实之前就对网络爬虫有点兴趣,这次正好用Python来试试。
事先准备:
搭建Python环境
https://www.python.org/downloads/
下载对应自己系统的安装包,我这里就直接选3.x版本了

之后就可以开始我们的Python之旅啦
目标是将自己csdn上的博文全部抓取下来
首先获取自己博文列表的网页源码,因为抓取时会有编码问题,所以这里直接将返回的html数据转换为utf-8编码,这样中文就不会变成unicode编码形式了

import urllib.request import reimport sysdef getHtmlInfo(url):    print('url:'+url)    return str(urllib.request.urlopen(url).read(),'utf-8')html=getHtmlInfo("http://blog.csdn.net/yeyinglingfeng?viewmode=contents")   

查看网页源代码后得知每篇博文的url所在

//目录视图下每篇文章的url<h1>    <span class="link_title"><a href="/yeyinglingfeng/article/details/76212176">        (6)birt笔记 - 通过传递变量来动态修改数据集SQL                    </a>    </span>        </h1>......

知道大致位置之后就可以使用正则表达式来筛选出所有的博文url
()表示分组,将括号的内容捕获到分组当中
.+表示至少是一个任意字符
?为懒惰查找,即匹配即可能少的字符串

def getArticleUrl(html):        reg=r'<span class="link_title"><a href="(.+?)">'        articleRe=re.compile(reg)        articleUrlList=re.findall(articleRe,html)        return articleUrlListarticleUrlList=getArticleUrl(html)

url中还缺少一部分,直接定义一个字符串,之后拼接上去即可

htmlStr='http://blog.csdn.net'

然后就可以通过和抓取http://blog.csdn.net/yeyinglingfeng?viewmode=contents一样的方式来遍历抓取博文

for articleUrl in articleUrlList:    articleHtml=getHtmlInfo(htmlStr+articleUrl)

然后进入一片自己的博文,查看源代码,看下具体的正文部分在哪里,然后用正则或者字符串截取操作来获取正文即可,这里因为我的csdn博文中还有各种代码块,图片,字体,所以正文中混着很多html代码,这里处理起来有点麻烦,大致思路也是正则去筛,就是类型有点多,应该会花点时间,这里就直接筛正文部分了

def saveInfo(info,fileName):    try:        fileAll='d:\\1\\python\\'+fileName+'.txt'        print(fileAll)        with open(fileAll,'w',encoding='utf-8') as file_write:            file_write.write(info)    except:        print('error:something faile')def getTitle(html,str):        reg=r'<span class="link_title"><a href="'+str+'">(.+?)</a>'        titleRe=re.compile(reg,re.S)        titleList=re.findall(titleRe,html)        return titleListdef getTime(html):        reg=r'<span class="link_postdate">(.+?)</span>'        timeRe=re.compile(reg)        timeList=re.findall(timeRe,html)        return timeList def getArticleInfo(html):        reg=r'<div id="article_content" class="article_content tracking-ad" data-mod=popu_307  data-dsm = "post" >(.+?)</div>'        articleRe=re.compile(reg,re.S)        articleList=re.findall(articleRe,html)        return articleList    #博文发表时间    time=getTime(articleHtml)[0].replace(':','.')    #博文标题    title=getTitle(articleHtml,articleUrl)[0].replace(' ','').replace('\r\n','').replace(':',' ').replace('/',' ')    #博文保存时用的文件名    fileName=time+' '+title    #博文正文内容    articleInfo=getArticleInfo(articleHtml)[0]    #保存博文    saveInfo(articleInfo,fileName)

整体完毕,对博文的正文部分,还需要进行更加细致的筛选,剔除掉多余的html代码。所用到东西其实很少,比较重要的是urllib.request.urlopen(url)抓取页面源代码,在2.X中是import urllib urllib.urlopen(url)。其余就是对Python数组,正则的运用了,拿来熟悉Python还是不错的。
过程中遇到很多比较抓狂的编码问题,比如在直接抓取博文后进行保存时,因为我这里使用cmd跑的Python,而cmd默认编码应该是GBK,然后就会报’Xxxx’字符无法转换为gbk的问题,然后不知道的就很抓狂了,明明上面基本全用的utf-8,这个gbk是哪里跑出来的= =。这时在with open文件时加上utf-8编码应该就能解决大部分类似问题,不行的话还需要将Python默认编码设置为utf-8。然后在截取返回的页面源码时,有时需要去掉包含的回车。一般都默认是’\n’,但是这里是’\r”\n’,之前我在用replace去除多余回车时,就与到了残留了’\r’,然后获得的字符串在与其他字符串进行拼接时,会出现覆盖现象,大致就是

A='1234567'B='AB\r\nC'B=B.replace('\n','')print(A+B)#输出ABC4567#大致这样的意思,当时找问题的地方简直抓狂,最后才发现回车还附带\r = =

总感觉之后编码问题会是一个大坑= =
整体代码文件
https://github.com/SecondMagic/-1-python-csdn
这里写图片描述


10.25更新
使用HTMLParser对截取到的正文部分进行进一步的筛选,去除多余的html
继承HTMLParser,并对handle_data方法进行重写,handle_data方法在遇到html标签中间的文本内容时将会触发,这里将获得的文本内容拼接成正文,还会遇到空行较多的问题,还有原代码块部分会出现很多换行,需进一步进行处理

from html.parser import HTMLParserclass MyHTMLParser(HTMLParser):    def __init__(self):        HTMLParser.__init__(self)        self.htmlStr = ''    def handle_data(self, data):        self.htmlStr+=(data+'\n')....    #articleInfo为获取到的含html文本的正文部分    parser = MyHTMLParser()    parser.feed(articleInfo)    parser.close()    saveInfo(parser.htmlStr,fileName)

大致效果对比
这里写图片描述
这里写图片描述

原创粉丝点击