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

其实之前就对网络爬虫有点兴趣,这次正好用Python来试试。
事先准备:
搭建Python环境
https://www.python.org/downloads/
下载对应自己系统的安装包,我这里就直接选3.x版本了

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

import urllib.request 
import re
import sys

def 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 articleUrlList
articleUrlList=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 titleList
def 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 HTMLParser
class 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)

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

扫描二维码关注公众号,回复: 1072802 查看本文章

猜你喜欢

转载自blog.csdn.net/yeyinglingfeng/article/details/78332515
今日推荐