爬取博主所有文章並保存到本地(.txt版)--python3.6


閑話:

一位前輩告訴我大學期間要好好維護自己的博客,在博客園發布很好,但是自己最好也保留一個備份。

正好最近在學習python,剛剛從py2轉到py3,還有點不是很習慣,正想着多練習,於是萌生了這個想法——用爬蟲保存自己的所有文章

在查了一些資料后,慢慢的有了思路。

正文:

有了上面的思路后,編程就不是問題了,就像師傅說的,任何語言,語法只是很小的一部分,主要還是編程思想。於是邊看語法,邊寫程序,照葫蘆畫瓢,也算實現了既定的功能:

1、現在py文件同目錄下創建一個以博主名字為名的文件夾,用來存放爬取的所有文章。

2、暫時先保存成TXT文件,這個比較容易。但是缺點是無法保存圖片。后面在學習直接轉成PDF。

3、爬取完成后提醒我你爬取了多少片文章。

要懶就懶到位,最好不要讓我動一下手就自動爬取所有文章,但是。。。。還是要看一下自己的文章目錄的url吧、看一下自己有多少頁目錄吧,然后這兩個參數填進去之后,就完美了。

提示:使用chrome瀏覽器,在chrome下:先按F12進入開發者模式,在網頁上右鍵選中一塊區域,然后選擇【檢查】,在右側即可查看對應的HTML程序

主要函數的實現:

1、獲取所有文章的url:

def get_urls(url,pages):
    """
    獲取所有目錄下的所有文章url
    :param url: 某一頁目錄的url,去掉最后的數字
    :param pages: 一共需要爬取的頁數
    :return: 返回所有文章url的列表
    """
    total_urls = []

    for i in range(1,pages+1):      #根據一個目錄的url找到所有目錄

        url_temp = url + str(i)

        html = get_html(url_temp)   #獲取網頁源碼

        title_pattern = re.compile(r'<a.*?class="postTitle2".*?href="(.*?)">',re.S)    #文章url正則表達式

        url_temp2 = re.findall(title_pattern,html)     #找到一個目錄中所有文章的網址

        for _url in url_temp2:
            total_urls.append(_url)            #所有文章url放在一起
    return total_urls

關於正則表達式的選擇:這是我目錄中的兩篇文章標題的HTML程序:

可以發現,都在一對a標簽下,class屬性為:"postTitle n",其href屬性就是文章的url網址。

所以正則表達式可以寫為:re.compile(r'<a.*?class="postTitle2".*?href="(.*?)">',re.S)

最后調用append方法,將所有文章的url放在一個list列表里面。

 

2、獲取文章標題:

def get_title(url):
    """
    獲取對應url下文章的標題,返回標題
    :param url:
    :return:
    """
    html_page = get_html(url)
    title_pattern = re.compile(r'(<a.*id="cb_post_title_url".*>)(.*)(</a>)')
    title_match = re.search(title_pattern,html_page)
    title = title_match.group(2)
    return title

這個也很簡單,檢查元素我們可以發現:

與上面一樣,這個正則表達式可以選擇:re.compile(r'(<a.*id="cb_post_title_url".*>)(.*)(</a>)')

然后保留其第二個分組就是文章標題。

 

3、獲取正文:

def get_body(url):
    """
    獲取url下文章的正文內容
    :param url:
    :return:
    """
    html_page = get_html(url)
    soup = BeautifulSoup(html_page,'html.parser')   #HTML文檔解析器
    div = soup.find(id = "cnblogs_post_body")
    return div.get_text()

使用BeautifulSoup模塊,創建一個對象,然后使用  soup.find()方法,搜索ID為  "cnblogs_post_body" 的標簽,返回標簽內的文檔內容。

 

4、下載單個文件:

def save_single_file(url):
    """
    首先在py文件同目錄下創建一個以博主名字為名的文件,用來存放爬取的所有文章
    將文章正文保存在txt文件中,名字為文章標題
    有些文章的標題可能不適合直接作為txt文件名,我們可以忽略這些文章
    :param url:
    :return:
    """
    global article_count    #使用全局變量,需要在函數中進行標識
    title = get_title(url)
    body = get_body(url)

    #獲取當前目錄文件,截取目錄后,並自動創建文件
    FILE_PATH = os.getcwd()[:-0]+author+'_''text\\'
    if not os.path.exists(FILE_PATH):
        os.makedirs(FILE_PATH)

    try:
        filename = title + '.txt'
        with open('D:\learning python\coding_python3.6\cnblog\\Andrew_text\\'+filename,'w',encoding='utf-8') as f:
            f.write(body)       #正文寫入文件
            article_count+= 1   #計數變量加1,統計總的下載文件數
    except:
        pass

    print(title+"  file have saved...")     #提示文章下載完畢

對於 os.getcwd()方法,

如果a.py文件存放的路徑下為:D:\Auto\eclipse\workspace\Testhtml\Test

通過os.getcwd()獲取的路徑為:D:\Auto\eclipse\workspace\Testhtml\Test

使用os.getcwd()[:-4]截取到的路徑為:D:\Auto\eclipse\workspace\Testhtml\ ,注意這個-4是在當前目錄字符串下,向前截取4個字符后的目錄。不想截取的話,直接省略數字,但是要有  [:]

使用下面的命令則在3步驟下新建文件夾,名為:變量author_text

    #獲取當前目錄文件,截取目錄后,並自動創建文件
    FILE_PATH = os.getcwd()[:-0]+author+'_''text\\'
    if not os.path.exists(FILE_PATH):
        os.makedirs(FILE_PATH)

 

 5、最終下載:

def save_files(url,pages):
    """
    調用單個文件保存函數,循環保存所有文件
    :param url:傳入任意一個目錄的url,但是要注意去掉最后的數字。
    :return:
    """
    total_urls = get_urls(url,pages)
    print("get all the urls..."+'\n')
    print(total_urls)      #獲取的文章url正確

    for urls in total_urls:
         save_single_file(urls)

    #輸出下載的總文章數
    print('\n' + "total article count is :%d"%article_count)

 

 運行結果:

 

參考資料:

項目啟發:http://www.cnblogs.com/xingzhui/p/7881905.html

正則表達式:https://blog.csdn.net/qq_878799579/article/details/72887612

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM