1. 程式人生 > >一鍵下載:將知乎專欄匯出成電子書

一鍵下載:將知乎專欄匯出成電子書

老是有同學問,學了 Python 基礎後不知道可以做點什麼來提高。今天就再用個小例子,給大家講講,通過 Python爬蟲 ,可以完成怎樣的小工具。

在知乎上,你一定關注了一些不錯的專欄(比如 Crossin的程式設計教室)。但萬一有那麼一天,你喜歡的答主在網上被人噴了,一怒之下刪帖停更,這些好內容可就都看不到了。儘管這是小概率事件(可也不是沒發生過),但未雨綢繆,你可以把關注的專欄匯出成電子書,這樣既可以離線閱讀,又不怕意外刪帖了。

只是需要工具和原始碼的可以拉到文章底部獲取程式碼。

【最終效果】

執行程式,輸入 專欄的 id ,也就是網頁地址上的路徑:

之後程式便會自動抓取專欄中的文章,並按釋出時間合併匯出為 pdf

檔案。

【實現思路】

這個程式主要分為三個部分:

  1. 抓取專欄文章地址 列表
  2. 抓取每一篇文章的 詳細內容
  3. 匯出 PDF

1. 抓取列表

在之前的文章 爬蟲必備工具,掌握它就解決了一半的問題 中介紹過如何分析一個網頁上的請求。按照其中的方法,我們可以通過 開發者工具Network 功能 找出專欄頁面獲取詳細列表的請求:



https://www.zhihu.com/api/v4/columns/crossin/articles

觀察返回結果中發現,通過 nextis_end 的值,我們能獲取下一次列表請求的地址(相當於向下滾動頁面的觸發效果)以及判斷是否已經拿到所有文章。

data

中的 idtitleurl 就是我們需要的資料。因為 url 可以通過 id拼出,所以我們的程式碼裡未儲存它。

使用一個 while 迴圈,直到抓取完所有文章的 idtitle,儲存在檔案中。



while True:
    resp = requests.get(url, headers=headers)
    j = resp.json()
    data = j['data']
    for article in data:
        # 儲存id和title(略)
    if j['paging']['is_end']:
        break
    url = j['paging']['next']
    # 按 id 排序(略)
    # 匯入檔案(略)

2. 抓取文章

有了所有文章的 id / url,後面的抓取就很簡單了。文章主體內容就在 Post-RichText 的標籤中。

需要稍微花點功夫的是一些文字上的處理,比如原頁面的圖片效果,會加上 noscript標籤和 `、highlight">



url = 'https://zhuanlan.zhihu.com/p/' + id
html = requests.get(url, headers=headers).text
soup = BeautifulSoup(html, 'lxml')
content = soup.find(class_='Post-RichText').prettify()
# 對content做處理(略)
with open(file_name, 'w') as f:
    f.write(content)

到這一步,就已經完成了所有內容的抓取,可以在本地閱讀了。

3. 匯出 PDF

為了更便於閱讀,我們使用 wkhtmltopdf + pdfkit ,將這些 HTML 檔案打包成 PDF。

wkhtmltopdf 是一個 HTML 轉 PDF 的工具,需要單獨安裝,具體可參考它的官網介紹。

pdfkit 是對此工具封裝的 Python 庫,可從 pip 安裝:



pip install pdfkit

使用起來很簡單:



# 獲取htmls檔名列表(略)
pdfkit.from_file(sorted(htmls), 'zhihu.pdf')

這樣就完成了整個專欄匯出。

不僅是知乎專欄,幾乎大多數資訊類網站,都是通過 1.抓取列表 2.抓取詳細內容 這兩個步驟來採集資料。因此這個程式碼稍加修改,即可用在很多別的網站上。只不過有些網站需登入後訪問,那麼就需要對 headers 裡的 cookie 資訊進行設定。此外,不同網站的請求介面、引數、限制都不盡相同,所以還是要具體問題具體分析。

關於這些爬蟲的開發技巧,都可以在我們的 爬蟲實戰 課程中學到。 有需要的請在公眾號裡回覆 爬蟲實戰

【原始碼下載】

獲取知乎專欄下載器原始碼,請在公眾號( Crossin的程式設計教室 )裡回覆關鍵字 知乎

除了程式碼外, 本專欄打包好的 PDF 也一併奉上,歡迎閱讀與分享。

════

其他文章及回答:

歡迎搜尋及關注: Crossin的程式設計教室