暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

python3.7爬取新浪博客所有文章存入word

染卷 2020-04-17
397

本文使用python抓取新浪博客全部文章的源码基于网上旧版教程,因网上同类文章重复过多,很多站点的python爬取教程都是一模一样,该教程的原始出处已无法考证。现在网上流传的教程基本已经无法在python3.7版本下运行了,需要进行不少修改,这次的代码写的比较仓促,有很多累赘代码没有时间删除优化。另外在使用这个python爬取的过程中发现对表格的支持不友好,另外不支持爬取图片。爬取图片的教程网上有很多,也可以参考我之前的文章:python3.7保存防盗链图片referer

本代码基本保留了网上流传老版本的所有代码,并已针对python3.7环境做出相应的修改(同时也保留了老版本大代码,但是注释掉了否则无法运行)

  1. import urllib

  2. #import urllib2

  3. import urllib.request

  4. import re

  5. #from urllib import urlopen

  6. from urllib.request import urlopen

  7. class Tool:

  8.     #去除img标签,7位长空格

  9.    removeImg = re.compile('<img.*?>| {7}|')

  10.    #删除超链接标签

  11.    removeAddr = re.compile('<a.*?>|</a>')

  12.    #把换行的标签换为\n

  13.    replaceLine = re.compile('<tr>|<div>|</div>|</p>')

  14.    #将表格制表<td>替换为\t

  15.    replaceTD= re.compile('<td>')

  16.    #把段落开头换为\n加空两格

  17.    replacePara = re.compile('<p.*?>')

  18.    #将换行符或双换行符替换为\n

  19.    replaceBR = re.compile('<br><br>|<br>')

  20.    #将其余标签剔除

  21.    removeExtraTag = re.compile('<.*?>')

  22.    def replace(self,x):

  23.        x = re.sub(self.removeImg,"",x)

  24.        x = re.sub(self.removeAddr,"",x)

  25.        x = re.sub(self.replaceLine,"\n",x)

  26.        x = re.sub(self.replaceTD,"\t",x)

  27.        x = re.sub(self.replacePara,"\n    ",x)

  28.        x = re.sub(self.replaceBR,"\n",x)

  29.        x = re.sub(self.removeExtraTag,"",x)

  30.        #strip()将前后多余内容删除

  31.        return x.strip()


  32. class XLBK:

  33.    def __init__(self,baseUrl,articleTag,fileName):

  34.        self.baseURL=baseUrl

  35.        self.tool=Tool()

  36.        self.file=None

  37.        self.article=1

  38.        self.defaultTitle=u'新浪博客'

  39.        self.articleTag=articleTag

  40.        self.fileName=fileName


  41.    def getPage(self,pageNum):

  42.        try:

  43.            url=self.baseURL+str(pageNum)+'.html'

  44.            print ('即将抓取的网页:'+url)

  45.            #request= urllib2.Request(url)

  46.            request= urllib.request.Request(url)

  47.            #response=urllib2.urlopen(request)

  48.            response=urllib.request.urlopen(request)

  49.            return response.read().decode('utf-8')


  50.        #except urllib2.URLError ,e:

  51.        except urllib.error.URLError as e:

  52.            if hasattr(e,"reason"):

  53.                #print u"连接新浪博客失败,错误原因",e.reason

  54.                print ("连接新浪博客失败,错误原因",e.reason)


  55.                return None

  56.    def getTitle(self,page):

  57.        pattern = re.compile('blogname.*?blognamespan.*?>(.*?)</span>', re.S)

  58.        result = re.search(pattern,page)

  59.        print ("title"+result.group(1).strip())

  60.        if result:

  61.            return result.group(1).strip()

  62.        else:

  63.            return None


  64.    def getPageNum(self,page):

  65.        #pattern= re.compile(ur'<span style.*?>共(.*?)页</span>',re.S)

  66.        pattern= re.compile(u'<span style.*?>共(.*?)页</span>',re.S)

  67.        result = re.search(pattern,page)

  68.        if result:

  69.            #print "pagenum"+result.group(1).strip()

  70.            return result.group(1).strip()

  71.        else:

  72.            print (result)

  73.            return 1


  74.    def getContent(self,page):

  75.        pattern = re.compile('<span class="atc_title">.*?<a.*?href.*?.html">(.*?)</a>.*?</span>',re.S)

  76.        items = re.findall(pattern,page)

  77.        contents = []

  78.        for item in items:

  79.            content = "\n"+self.tool.replace(item)+"\n"

  80.            contents.append(content.encode('utf-8'))

  81.            #print (content)# 返回博客标题了

  82.        return contents


  83.    def getUrl(self,page):

  84.        pattern =re.compile('<span class="atc_title">.*?<a.*?href="(.*?)">.*?</a>.*?</span>',re.S)

  85.        items = re.findall(pattern,page)

  86.        urls = []

  87.        for item in items:

  88.            url = item

  89.            #urls.append(url.encode('utf-8')) #会导致首部多出字符 b'

  90.            urls.append(url)


  91.            #print (url) #返回博客url

  92.        return urls



  93.    def getText(self,url):

  94.         text=urlopen(url).read().decode('utf-8')

  95.         start=text.find(u"<!-- 正文开始 -->")

  96.         print (start)

  97.         end=text.find(u"<!-- 正文结束 -->")

  98.         print (end)

  99.         text=text[start:end]

  100.         text = re.sub(re.compile('<p.*?>'),"\n    ",text)

  101.         text = re.sub(re.compile('<p>'),"\n    ",text)

  102.         text=re.sub(r'<(S*?)[^>]*>.*?|<.*? /> ','',text)

  103.         text=re.sub(r'&[^>]*?\;',' ',text)

  104.         #return text.encode('utf-8') #编码混乱

  105.         return text


  106.    def setFileTitle(self,title):

  107.        if title is not None:

  108.            self.file = open(title + ".doc","w")

  109.        else:

  110.            self.file = open(self.defaultTitle + ".doc","w")



  111.    def writeData_original(self,contents,urls):

  112.        for item in contents:

  113.            #print('item=='+str(item))

  114.            if self.articleTag == '1':


  115.                articleLine = "\n" + str(self.article) + u"--------------------------------------------------------------------------------\n"

  116.                self.file.write(articleLine)

  117.            #self.file.write(item) #TypeError: write() argument must be str, not bytes

  118.            self.file.write(str(item))

  119.            #print item

  120.            #self.file.write(urls[contents.index(item)]) #TypeError: write() argument must be str, not bytes

  121.            self.file.write(urls[contents.index(str(item))])

  122.            #print urls[contents.index(item)]

  123.            text=self.getText(urls[contents.index(item)])

  124.            print (text)

  125.            self.file.write(str(text))

  126.            self.article += 1


  127.    def writeData(self,contents,urls):

  128.        print(urls)

  129.        for item in urls:

  130.            #item ='http://blog.sina.com.cn/s/blog_67493dad0102uxwl.html'

  131.            print('item=='+str(item))

  132.            if self.articleTag == '1':


  133.                articleLine = "\n" + str(self.article) + u"--------------------------------------------------------------------------------\n"

  134.                self.file.write(articleLine)

  135.            #self.file.write(item) #TypeError: write() argument must be str, not bytes

  136.            self.file.write(str(item))

  137.            #print item

  138.            #self.file.write(urls[contents.index(item)]) #TypeError: write() argument must be str, not bytes

  139.            #self.file.write(urls[contents.index(str(item))])

  140.            item=str(item)

  141.            item=item.replace("b'", "");

  142.            #self.file.write(contents[urls.index(item)])


  143.            #print urls[contents.index(item)]

  144.            #text=self.getText(urls[contents.index(item)])

  145.            text=self.getText(item)

  146.            #text=self.getText('http://blog.sina.com.cn/s/blog_67493dad0102uxwl.html')



  147.            print (text)

  148.            self.file.write(str(text))

  149.            self.article += 1


  150.    def start(self):

  151.        indexPage = self.getPage(1)

  152.        pageNum = self.getPageNum(indexPage)

  153.        title = self.getTitle(indexPage)

  154.        self.setFileTitle(self.fileName)

  155.        if pageNum == None:

  156.            print ("URL已失效,请重试")

  157.            return

  158.        try:

  159.            print ("该博客共有" + str(pageNum) + "页")

  160.            for i in range(1,int(pageNum)+1):

  161.                print ("正在写入第" + str(i) + "页数据")

  162.                page = self.getPage(i)

  163.                contents = self.getContent(page)

  164.                urls =self.getUrl(page)

  165.                self.writeData(contents,urls)

  166.        #except IOError,e:

  167.        except IOError as e:

  168.            print ("写入异常,原因" + e.message)

  169.        finally:

  170.            print ("写入任务完成")




  171. #print u"打开一个新浪博客的博文目录\n如http://blog.sina.com.cn/s/articlelist_1866629225_0_1.html \n那么该博客的代号为1866629225_0_   \n请输入博客代号"

  172. #baseURL = 'http://blog.sina.com.cn/s/articlelist_' + str(raw_input(""))

  173. #baseURL = 'http://blog.sina.com.cn/s/articlelist_' + str(input(""))

  174. #

  175. #假设本例要测试的新浪博客全部文章目录地址为:http://blog.sina.com.cn/s/articlelist_1732853165_0_1.html

  176. baseURL =  'http://blog.sina.com.cn/s/articlelist_1732853165_0_' #这里是直接赋值的形式

  177. #articleTag = raw_input("是否写入文章编号信息,是输入1,否输入0\n")

  178. articleTag = input("是否写入文章编号信息,是输入1,否输入0\n") # 运行后输入 1

  179. #fileName=raw_input("请输入保存文档的名称\n")

  180. fileName=input("请输入保存文档的名称\n") #文件名可以随便输入-------也可以直接赋值  fileName=sina_blog_save

  181. xlbk = XLBK(baseURL,articleTag,fileName)

  182. xlbk.start()


测试的时候爬取新浪博客文章的速度还可以,就是爬取的内容还有进一步优化的空间,后面有时间再优化吧。不得不说python就是强大,各种库不是吹的。

基于互联网精神,在注明出处的前提下本站文章可自由转载!

本文链接:https://ranjuan.cn/python-crawler-sinablog/


文章转载自染卷,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论