(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)

大致效果對比
這裏寫圖片描述
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章