python下載漫畫

下載漫畫的腳本

身爲漫畫迷,一直想直接將漫畫下載到電腦上看,於是就有這個python腳本。

系統:Ubuntu 14.04
python版本:2.7.6
用到的python庫有:

  • os (操作系統接口的標準庫,用於創建文件)
  • sys (標準庫,獲取命令行參數)
  • string (字符串操作的標準庫,用於將字符串中的數值轉換爲整型)
  • getopt (對命令行參數進行處理)
  • lxml (當中的html,相當於Jsoup,這裏用於快速查找網頁的元素)
  • requests (通過URL獲取網頁)
  • urllib2 (作用和requests差不多)

其中非標準庫getopt、lxml、requests、urlslibs可以通過pip安裝。

思路:

  1. 選擇漫畫網站進行解析,顯示漫畫章節
  2. 選擇漫畫章節,找到本章漫畫圖片的路徑
  3. 按漫畫圖片的路徑下載到本地保存

要求:瞭解Python、XPath、URL、html即可。


步驟

1.解析漫畫章節列表

以納米漫畫網下的盤龍爲例(以前叫國漫吧,很多國漫都能看,我挺喜歡的,不過chromium卻顯示這網站有毒*=*,注意)
漫畫章節

爲了方便下載,需要將漫畫的每個章節標題和相應的鏈接記錄下來。
查看章節列表的源碼,發現章節是用無序列表關聯的,查看其中一個章節的XPath,/html/body/div[2]/div[1]/div[2]/div[3]/ul/li[1]/a。但是每個章節的xpath都是不一樣的,我們不可能一個一個地計算,這時就要找到它們的共同點。

這裏寫圖片描述

很明顯,可以用含class的xpath代替,xpath可以理解爲網頁元素的標識、位置。
這裏用//div[@class=”tab-content tab-content-selected zj_list_con autoHeight”]/ul[@class=”list_con_li autoHeight”]/li代替每個章節,
那麼章節標題就是
**//div[@class="tab-content tab-content-selected zj_list_con autoHeight"]/ul[@class="list_con_li autoHeight"]/li/a/span[@class="list_con_zj"]/text()**
章節的鏈接就是**//div[@class="tab-content tab-content-selected zj_list_con autoHeight"]/ul[@class="list_con_li autoHeight"]/li/a[@href]/@href**

代碼如下

#獲取漫畫的目錄
def getIndexLinkFromDirectory(comic_directory_url):
    page = requests.get(comic_directory_url)
    tree = html.fromstring(page.content)
    comic_title = tree.xpath('//div[@class="comic_deCon"]/h3[1]/a/text()')
    chapter_link = tree.xpath('//div[@class="tab-content tab-content-selected zj_list_con autoHeight"]/ul[@class="list_con_li autoHeight"]/li/a[@href]/@href')
    chapter_title = tree.xpath('//div[@class="tab-content tab-content-selected zj_list_con autoHeight"]/ul[@class="list_con_li autoHeight"]/li/a/span[@class="list_con_zj"]/text()')    
    #print "Cretae directory"
    return   comic_title[0],chapter_link,chapter_title

主要就是以漫畫章節目錄網頁的URL作爲參數,並通過requests獲得這一網頁page,然後用html生成tree,在tree中可以通過xpath方便地獲取網頁元素,即章節標題和鏈接,以及漫畫名稱,並返回。
注意,python可以在一個函數中返回多個值,所以這裏依次返回漫畫名稱、章節標題數組和鏈接數組,其中後兩者有對應關係(同一下標的標題和鏈接相關)。


2.解析獲得漫畫圖片

以134話來看源碼
漫畫圖片

圖片元素

漫畫圖片的地址是http://cartoon.kdm8.com/?u=/manhuatuku/12757/manhua_12_20160225_2016022508144669474.jpg,我們要做的就是獲取這章節所有圖片的地址。爲了流暢快速,一般網站可能會將這些圖片地址保存到客戶端的瀏覽器中,也就是JS裏面。這時再看回網頁源碼,發現在某段的JS代碼裏就有,不過就是有點暈。

JS圖片地址

本頁的圖片地址和下一頁的圖片地址都在,很明顯這就是我們要的這一章的圖片地址了,這就方便下載。分析這段JS,可以發現在”page_url”的鍵值對裏面,而且以”|”分隔每個圖片地址。

代碼如下

#獲取一章節漫畫的鏈接
def getPictureUrls(data):    
    page_url = "\"page_url\":\""
    if page_url in data:        
        index = data.find(page_url)
        page_url = data[(index+len(page_url)):data.find("\"",index+len(page_url))]    
        return page_url.split("||")

主要是將requests獲得的網頁內容作爲參數data傳入,然後提取圖片地址,即”page_url”:”…..”這個鍵值對,然後在用”|”劃分爲地址數組並返回。


3.下載漫畫圖片到本地

通過上一步獲取圖片地址後,就可以通過其讀取圖片數據並保存到本地上。爲了方便,依次將圖片下載保存到以章節標題命名的文件夾中。

先嚐試直接下載是否被網站filter,有些網站會過濾掉這種外部請求

直接圖片

明顯能訪問,所以可行。

代碼如下

#下載漫畫到本地目錄中
def downloadPicture(pic_urls,base_directory):
    total = len(pic_urls)
    print "開始下載..."    
    for i in xrange(total):
        print "Downloading %d in %d" % (i+1, total)
        url = pic_urls[i].replace("\\","").replace("|","")
        f = urllib2.urlopen(url)
        data = f.read()
        with open(base_directory+"/%03d.jpg" % i,"wb") as pic:
            pic.write(data)
    print "下載完成"

以圖片地址數組爲參數pic_urls,本地目錄名(圖片保存)爲參數base_directory,依次通過urllibs下載到base_directory中,並用格式化字符串按順序重命名。
注意,因爲linux系統下文件路徑以”/“爲分隔符,所以如果要在windows下適用,文件名(”/%03d.jpg”)也要相應修改。


4.查找漫畫

一開始總不能直接輸入漫畫的網址,因爲不知道的,所以就需要實現查找功能,即輸入漫畫名後在網站上進行查找。

看回這網站的查找界面,嘗試查找盤龍
查找界面

可見網址的形式爲http://nmmanhua.com/search/?key=盤龍,那說明只要將搜索的漫畫名組成http://nmmanhua.com/search/?key=漫畫名再處理即可。

而搜索結果列表如圖
這裏寫圖片描述

同理,漫畫的XPath是//span[@class=”comic_list_det”]/,那麼標題就爲//span[@class=”comic_list_det”]/h3/a/text(),鏈接就是//span[@class=”comic_list_det”]/a/@href

代碼如下

#根據漫畫名查找,返回漫畫名和相應的鏈接    
def searching(content):
    print "查找中....."
    search_url = "http://nmmanhua.com/search/?key="+content #調用漫畫網站進行搜索
    page = requests.get(search_url)
    tree = html.fromstring(page.content)
    comic_title = tree.xpath('//span[@class="comic_list_det"]/h3/a/text()') #顯示漫畫名
    comic_link = tree.xpath('//span[@class="comic_list_det"]/a/@href')  #記錄漫畫的鏈接
    print "查找完成"
    return comic_title,comic_link

和第一步很相似,只是這裏返回漫畫標題數組和鏈接數組。


顯示

主要時通過上述處理後,獲得相應的相關數組,按順序顯示。
輸入相應的下標即爲選擇下載。

顯示搜索結果

搜索盤龍
1

代碼如下

#顯示漫畫搜索的結果
def showSearchResult(comic_title,comic_link):
    for i in xrange(len(comic_title)):
        print "%d.%-15s" % (i+1,comic_title[i])
    print "共找到 %d" % len(comic_title)

引用searching(content)後,格式化輸出。


顯示漫畫目錄

代碼如下

#顯示漫畫目錄
def showDirectory(comic_title,chapter_link,chapter_title):
    print "Title : ",comic_title
    for i in xrange(len(chapter_title)):
        print "%3d.%-15s" % (i+1,chapter_title[i])

引用getIndexLinkFromDirectory(comic_directory_url)後,格式化輸出。

下載第133話
2

顯示下載結果

下載自動保存到本地
3

下載後看漫畫
這裏寫圖片描述


總結

  1. 只是CUI,沒有GUI。這個腳本爲命令行界面,目前只是對納米漫畫網進行查找、下載,不過道理一樣。
  2. getopt處理參數,可以添加更多如-d 網址options,不過這裏只處理了-h-s
  3. 如果想同時用作圖片查看的話,可以使用python出名的PIL實現。
  4. 要跨平臺的話,就要修改文件名中的路徑分隔符才行。

Future
1. 想嘗試用Java實現,因爲Jsoup和lxml的html是一樣的道理,只是將xpath改用jquery表達式而已。
2. 寫一個Android端的app,也用於下載漫畫。現在困在怎樣異步獲取漫畫章節等信息並更新。

完整代碼:http://download.csdn.net/detail/cceking/9586938

發佈了49 篇原創文章 · 獲贊 16 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章