Python漫畫爬蟲——漫畫喵的100行代碼逆襲

2021-02-19 藍橋雲課精選

這次的博客,講的是使用python編寫一個爬蟲工具。為什麼要寫這個爬蟲呢?原因是小喵在看完《極黑的布倫希爾特》這個動畫之後,又想看看漫畫,結果發現各大APP都沒有資源,最終好不容易找到一個網站可以看,但是由於網速太渣,看起來額外的費勁。這時候如果能提前下載下來就好了。

先上項目地址(github):https://github.com/miaoerduo/cartoon-cat 。歡迎大家隨時forkstar和指教。

原因就是這樣,作為技術喵,任何問題都不能阻礙一顆愛漫畫的心。所以問題就來了,挖掘機技修哪家強?

在bing上搜索Python、爬蟲框架。找到大家常用的框架。

Scrapy似乎是個很不錯的選擇。至於相對於其他框架的優點,小喵沒有細查,至少這個框架是之前聽過的。但是在實現的時候發現有一些問題,scrapy不能直接抓取動態的頁面。小喵需要抓取的網站的漫畫都是使用Ajax生成的。需要自己分析各種數據,這個有點麻煩。

那麼有沒有可以渲染頁面的工具呢?像瀏覽器一樣的?有。

這裡介紹兩個工具:

PhantomJs,可以理解是一個瀏覽器。不過它沒有界面,我們可以通過js的代碼模擬用戶的行為。這就要求了解它的api並有js基礎了。

Selenium,這是個瀏覽器自動化測試框架。它依賴於瀏覽器(這個瀏覽器也可以是PhantomJs),通過Selenium可以模擬用戶的行為。而且有Python接口,所以相對簡單一些。

我們這個爬蟲使用selenium + phantomjs來實現。

喲,這個爬蟲軟體應該有個響噹噹的名字。。。就叫漫畫喵吧,英文名Cartoon Cat

下面我們一點點的介紹這個爬蟲的實現過程吧。

一、初生-環境搭建

小喵這裡選用Python作為開發語言,框架是selenium。原因是python經常用來寫爬蟲,selenium可以用來模擬用戶行為,PhantomJs是可選的,不過小喵最終會在一個伺服器上運行,所以也是需要的。

為了不影響本機上的python,我們還需要使用virtualenv來創建一個獨立的python環境。具體步驟如下:

1. 安裝virtualenv

virtualenv是一個常用的用來創建python環境的工具。小喵用這個有兩個原因,一是為了不汙染本機的環境,二是在本機直接安裝庫的時候出了一個權限的問題。

virtualenv的安裝十分簡單,使用pip工具就可以安裝。

待程序執行結束,你就會開心的發現自己已經有了virtualenv這個工具了。

2. 創建python環境

virtualenv的使用非常的方便。

建立新的運行環境:virtualenv <env-name>

進入相應的獨立環境:source <env-path>/bin/activate

執行完第一個指令後,就會創建成功一個python環境,執行第二個指令後,就會發現命令行的起始位置有變化。這時候python、pip等工具就變成使用這個新環境的了,當然也可以使用which python來查看。

3. 安裝selenium

進入新環境後,pip安裝的依賴庫都會在新環境中安裝,不會影響主機自身的python。使用pip 安裝selenium:

至此,我們的基本環境就搭建完了。

4. 安裝PhantomJs

這個只在從官網上下載就可以:http://phantomjs.org/download.html

小喵的本地實驗環境是Mac,所以下載了Mac版本。解壓之後就可以使用。

二、尋覓-搜資源

小喵想看的這個漫畫貌似各大網站都沒有資源,在費了九牛二虎之力後,終於找到了一個網站!http://www.tazhe.com/mh/9170/。

每個網站的結構都不相同,因此都需要定製一套爬蟲程序。本文的爬蟲就只能針對這個漫畫網站使用,喵粉們需要爬其他網站的話,需要自己做相應的修改。

三、分析-資源解析

這裡需要解析兩個頁面,一個是漫畫的首頁,比如前面的:http://www.tazhe.com/mh/9170/

另一個就是具體章節的頁面。

1. 首頁

為了減小圖片的大小,小喵把窗口做了縮放。首頁大致是這個樣子。

圖1 漫畫首頁

各類信息十分的明了。我們關注的就是下面的漫畫列表。通過Chrome強大的審查元素的功能,我們立刻就能定位到章節的位置。(對著感興趣的位置->右鍵->審查 就能找到)

圖2 章節的節點

可以看到,章節所在的區域的id是play_0,學過前端的童鞋都應該知道,一個頁面中id通常唯一標示一個節點。因此如果我們能夠獲取這個頁面的話,查找id為play_0的節點就能一下子縮小搜索範圍。

而每個章節的信息都是一個a標籤,標籤的href是對應章節的具體網址,標籤的文本部分是章節名。這樣相對關係就得出了:div#play_0 > ul > li > a。

首頁的分析就到此結束。

2. 章節頁面

我們隨意打開一個具體章節的頁面。比如:http://www.tazhe.com/mh/9170/1187086.html

引入眼帘的是一個很乾淨的頁面(簡直是漫畫界的清流,好多漫畫網站上全部是廣告)。

我們把滑鼠放在圖片這個區域->右鍵->審查

咦,我們的右鍵怎麼按不了?

其實呢,這個現象在小說網站上遇到的機會會更多。當我們看到比較優美的文字或是炫酷的圖片,都會下意識的選中->右鍵->保存。而很多時候,這些資源都是有版權的。並不應該隨意的傳播(狠狠的打了自己的臉/(ㄒoㄒ)/~~)。因此限制滑鼠右鍵會是一個很簡單卻有效的辦法。

那麼我們如何繞過這個陷阱呢?

很簡單,我們不用右鍵即可。打開瀏覽器的開發者工具選項,找到elements這個選項。可以看到一個複雜的結構(其實和上面審查元素之後的結果一樣)。之後不斷的選中標籤,當標籤被選中時,左側頁面中對應的位置會有藍色。多試幾次,最終就能找到對應的位置。

圖3 漫畫圖片

這是一個img標籤,對應的id是qTcms_pic。這樣找到這個id,就能找到這個img標籤,根據src就能找到圖片的具體URI地址。

接下來是找到下一張圖片的地址。這時候需要查看下一頁這個按鈕的內容。用相同的方法,很容易定位成功。

圖4 下一頁

小喵本來是用scrapy來做爬蟲的,看到這裡的時候就果斷放棄了。我們分析一下,選中的a標籤的代碼如下:

<a href="javascript:a_f_qTcms_Pic_nextUrl_Href();" title="下一頁"><span>下一頁</span></a>

比較簡單的網站,「下一頁」可以用真的a標籤和href屬性來做。這樣的好處是實現比較簡單,壞處是一旦得到網頁源碼就能很容易的解析。而像scrapy這樣的爬蟲工具只能抓取靜態的代碼(動態的需要自己分析ajax,有點麻煩)。而顯然這裡的頁面是動態的,使用了ajax來實現。所以光是得到網頁源碼並不能真的得到圖片,而是必須讓其中的js代碼運行才可以。所以我們才需要使用瀏覽器或者PhantomJs這樣的可以執行js代碼的工具。

上面的a標籤的代碼告訴了我們很多信息。首先是告訴了我們,這個節點的位置,通過next這個類名可以方便的找到該節點(其實有兩個類名為next的按鈕,另一個在下面,但是功能都一樣)。其次,當這個按鈕被點擊時會調用:a_f_qTcms_Pic_nextUrl_Href()這個js函數。難道我們需要再研究這個函數?

不用。因為PhantomJs的角色就是一個瀏覽器。我們只需要向真正的用戶一樣點擊一下這個next按鈕,就會進入下一個頁面。/* 感受到這個工具的強大了嗎? */

3. 判斷章節的末尾

最後一個問題就是,如何判斷這個章節結束了?

我們跳到章節的最後一頁,然後再次點擊「下一頁」,這時候會出現一個彈窗。

圖5 最後一頁

多次試驗之後,我們會發現,只有在最後一頁的時候才會彈出這個彈窗,這樣的話,我們每抓取完一頁,點擊一次「下一頁」,判斷有無彈窗就知道是不是最後一頁了。在右側的開發者工具中我們能夠看到,這個彈窗是一個id為msgDiv的div(而且它的出現和消失是通過增減節點來實現的,另一種實現方法是將display設成none和block,這種情況可以根據display的屬性來判斷)。所以我們判斷這個節點存不存在就行了。

至此,兩種頁面的解析都完成了。下一步就開始我們的代碼實現吧。

四、逆襲——代碼實現1. selenium的簡單用法

from selenium import webdriver

browser = webdriver.Firefox()

# browser = webdriver.Safari()

# browser = webdriver.Chrome()

# browser = webdriver.Ie()

# browser = webdriver.PhantomJs()

browser.get('http://baidu.com')

print browser.title

# do anything you want

上面是一個簡單的例子,第一步import依賴的庫。

第二步,獲得一個瀏覽器實例。selenium支持多種瀏覽器。使用firefox之外的瀏覽器都需要下載驅動(selenium本身自帶了firefox的驅動)。驅動下載地址:https://pypi.python.org/pypi/selenium 。驅動下載完之後將它的路徑加入到PATH裡,確保驅動程序能夠被訪問到。或者顯式的把驅動程序的地址當參數傳入。像下面一樣調用:

browser = webdriver.PhantomJs('path/to/phantomjs')

第三步,用get的方式打開網頁。

最後,通過browser對象來解析和處理頁面。

2. 獲取章節的連結信息

在上面的解析頁面的時候,我們知道了章節信息的位置:div#play_0 > ul > li > a。這樣就可以解析出章節信息。browser支持一大堆的選擇器。大大簡化我們查找節點的工作。

from selenium import webdriver

 

if __name__ == "__main__":

    driver = "path/to/driver" # 驅動地址

    browser = webdriver.PhantomJS(driver) # 瀏覽器實例

 

    main_page = "http://www.tazhe.com/mh/9170/"

    browser.get(main_page) # 加載頁面

 

    # 解析出章節的元素節點

    chapter_elem_list = browser.find_elements_by_css_selector('#play_0 ul li a') # 通過css選擇器找出章節節點

    chapter_elem_list.reverse()  # 原本的章節是倒敘的

 

    chapter_list = []

    for chapter_elem in chapter_elem_list:

        # 元素的text和href屬性分別就是章節的名稱和地址

        chapter_list.append((chapter_elem.text, chapter_elem.get_attribute('href')))

 

    # chapter_list 就是章節的信息

3. 給定一個章節的地址,章節中的圖片

這一步涉及到節點的獲取、模擬滑鼠的點擊以及資源的下載。selenium的點擊實現特別的人性化。只需要獲取節點然後調用click()方法就搞定。資源的下載網上有許多教程,主要有兩個方法,通過模擬右鍵另存為,和獲取url用其他工具下載。考慮到這裡的右鍵不一定可用,而且操作有一點點複雜。小喵選用了第二種方案。

from selenium import webdriver

from selenium.common.exceptions import NoSuchElementException

import os

from os import path as osp

import urllib

 

# 一個簡單的下載器

download(url, save_path):

    try:

        with open(save_path, 'wb') as fp:

            fp.write(urllib.urlopen(url).read())

    except Exception, et:

        print(et)

 

if __name__ == "__main__":

    

    driver = "path/to/driver" # 驅動地址

    browser = webdriver.PhantomJS(driver) # 瀏覽器實例

 

    chapter_url = "http://www.tazhe.com/mh/9170/1187061.html"

    save_folder = "./download"

 

    if not osp.exists(save_folder):

        os.mkdir(save_folder)

 

    image_idx = 1

 

    browser.get(chapter_url) # 加載第一個頁面

 

    while True:

        # 根據前文的分析,找到圖片的URI地址

        image_url = browser.find_element_by_css_selector('#qTcms_pic').get_attribute('src')

        save_image_name = osp.join(save_folder, ('%05d' % image_idx) + '.' + osp.basename(image_url).split('.')[-1])

        download(image_url, save_image_name) # 下載圖片

 

        # 通過模擬點擊加載下一頁,注意如果是最後一頁,會出現彈窗提示

        browser.find_element_by_css_selector('a.next').click()

        try:

            # 找尋彈窗,如果彈窗存在,說明這個章節下載完畢,這個大循環也就結束了

            browser.find_element_by_css_selector('#bgDiv')

            break

        except NoSuchElementException:

            # 沒有結束彈窗,繼續下載

            image_idx += 1

五、終焉-寫在後面

至此,漫畫喵的設計思路和主要的代碼實現都介紹完了。上面的代碼只是用來示意,小喵自己下載漫畫用的代碼是另一套。github的地址是:https://github.com/miaoerduo/cartoon-cat 。項目只有100多行。不過也用了小喵不少的一段時間。

博客寫完了~小喵的漫畫也下完了~

圖6 下載好的漫畫

原文連結:http://www.miaoerduo.com/python/%E7%88%AC%E8%99%AB-%E6%BC%AB%E7%94%BB%E5%96%B5%E7%9A%84100%E8%A1%8C%E9%80%86%E8%A2%AD.html?utm_source=tuicool&utm_medium=referral

作者:MIAO

來源:喵耳朵

來呀,學習呀,點擊菜單【技術教程】,走到哪兒看到哪兒,就這麼愛學習~

相關焦點

  • Python三行代碼實時查看電影票房
    三行代碼教你解決,不,除了列印結果出來,其實只需要兩行代碼,馬上上車!tushare為我們提供實時30分鐘更新頻率的電影票房數據,包括:BoxOffice 實時票房(萬)Irank 排名MovieName 影片名boxPer 票房佔比 (%)movieDay 上映天數sumBoxOffice 累計票房(萬)time 數據獲取時間如果你還沒有安裝tushare的,可以在命令行輸入:pip install tushare
  • python為什麼叫爬蟲?為啥那麼多人通過python兼職都能掙不少錢?
    Python能做什麼之前有很多文章介紹python能做什麼。今天介紹python爬蟲的學習。網絡爬蟲 網絡爬蟲,也叫網絡蜘蛛(Web Spider)。爬蟲是根據網頁地址(URL)爬取網頁上的內容,這裡說的網頁地址(URL)就是我們在瀏覽器中輸入的網站連結。例如:https://www.baidu.com/,這就是一個URL。
  • python爬蟲實戰:爬取全站小說排行榜
    新筆趣閣是廣大書友最值得收藏的網絡小說閱讀網,網站收錄了當前.我就不打廣告了(其他滿足下文條件的網站也行,之前已經有做過簡單爬取章節的先例了,但效果不太理想,有很多不需要的成分被留下了,來連結:http://python.jobbole.com
  • Python爬蟲學到什麼程度就可以去找工作了?
    有朋友在群裡和大家討論,問的最多的問題就是,python 爬蟲學到什麼程度可以去找工作了,關於這點,和大家分享下我的理解。確立目標、了解需求首先我們要先定位自己的目標,當然我們先以爬蟲工程師來做個說明。
  • Python網絡爬蟲-第一行代碼-windows環境
    Python有強大的支持爬蟲功能的庫,是爬取網頁數據的首選。先看看是否有Python:cmd界面執行Python已經安裝完成,版本是2.7.15。可能是我安裝vue開發環境或者安卓開發環境的時候順便裝上了。然後檢查pip是否安裝。
  • Python爬蟲學習:抓取電影網站內容的爬蟲
    點擊藍字「python
  • 騰訊視頻 Python 爬蟲項目實戰
    可以用Firefox(Chrome也行)的inspect中的network這個tab來篩選查看可能的api接口。很快發現接口的URL是這個格式的:base_url = 'https://v.qq.com/x/bu/pagesheet/list?
  • 簡單幾步,100行代碼用Python畫一個蝙蝠俠的logo
    蝙蝠俠作為DC漫畫的核心人物之一,一直都受到廣大粉絲的喜愛,而筆者作為
  • Python爬蟲數據抓取方法匯總!所有方法都在此!
    2、python簡易代碼實現web抓取: 1 #coding=utf-8 2 3 import urllib,urllib2 4 5 #繼續以抓取豆瓣電影分類連結為例 6 7 movie_list = ['%E7%BA%AA%E5%BD%95%E7%89%
  • 深圳Python培訓班打造行業高標準Python人才
    Python火的原因1、python相比別的高級語言集成度更高,除了執行的效率低些,開源可以調用的類庫實在太多了,要實現一個功能,如果換作傳統的程式語言,需要實現基本的功能模塊,但直接調用類庫很方便的搞定,特別適合零基礎的學習, 幾行代碼就能實現很強大的功能。
  • 初學者如何用「python爬蟲」技術抓取網頁數據?
    而這裡的「技術手段」就是指網絡爬蟲。 今天,小編將與您分享一個爬蟲的基本知識和入門教程:什麼是爬蟲?網絡爬蟲,也叫作網絡數據採集,是指通過編程從Web伺服器請求數據(HTML表單),然後解析HTML以提取所需的數據。
  • 不用代碼玩轉爬蟲實例(1) - 抓取貓眼電影信息
    之前分享過一些關於用python抓取網頁數據的文章,可能有朋友會覺得自己不會寫代碼,或者寫代碼很費時費勁不夠方便。其實完全不用寫代碼一樣可以玩爬蟲!今天這篇文章開始就來陸續分享一下關於web scraper這款chrome插件的一些實例用法。關於web scraper,之前介紹了很多次了。
  • Python爬蟲高級之JS滲透登錄新浪微博|知了獨家研究
    所以,今天我給大家帶來用python模擬登錄新浪微博的過程。一、JS滲透爬蟲準備工作在介紹代碼之前,我先說一下代碼中用到的庫。1.rsa(是一個非對稱加密算法,需要pip安裝一下)2.Requests(可以說,只要有爬蟲的地方大多數都有它)3.base64(加密算法)python內置的4.time(時間模塊)5.json(處理字符串的
  • python爬蟲收入 - CSDN
    我利用Python爬蟲技術年掙10萬被動收入的方式,在正式聊Python爬蟲技術之前,先來說說掙錢的事,說說作為一個自由職業或兼職者怎麼利用爬蟲來掙錢。個人爬蟲掙錢方法大致如下爬蟲技術掙錢方法1:接外包爬蟲項目這是網絡爬蟲最通常的的掙錢方式,通過外包網站,熟人關係接一個個中小規模的爬蟲項目,一般向甲方提供數據抓取,數據結構化,數據清洗等服務。
  • 10行Python代碼教你免費觀看無廣告版的《慶餘年》騰訊視頻
    今天想秀下Python強大的主題是 —— 用10行代碼搞定各類app的廣告。本來這周是要發個關於如何用python打造屬於自己的iphone快捷方式的,結果因為本周一直沉迷在《慶餘年》中不能自拔,所以下周吧!最近《慶餘年》大火的同時,關於騰訊吃相的吐槽也是大火。
  • Python網頁爬蟲工具有哪些?
    不管文本處理,機器學習和數據發掘,都需求數據,除了通過一些途徑購買或者下載的專業數據外,常常需求我們自己著手爬數據,爬蟲就顯得分外重要。那麼,Python網頁爬蟲東西有哪些呢?1、ScrapyScrapy相Scrapy, a fast high-level screen scraping and web crawling framework for Python.信不少同學都有耳聞,課程圖譜中的許多課程都是依託Scrapy抓去的,這方面的介紹文章有許多,引薦大牛pluskid早年的一篇文章:《Scrapy 輕鬆定製網絡爬蟲》,歷久彌新。
  • 編寫你的第一個爬蟲程序
    因此,對於未來想進入中高級數據分析相關領域的朋友,掌握爬蟲就成為了必要不充分條件。《論語》有云:工欲善其事,必先利其器。市面上很多爬蟲類教程書籍,包括我非常喜歡的O』REILLY系列書籍,基本上都是以urllib、beautifulSoup等python庫入手。這些庫雖然功能強大,也具備一定的簡潔性,但是對於初學者而言,可以做的事真的比較少。
  • 開課吧Python:Python爬蟲是什麼?爬蟲工程師薪資怎麼樣?
    Python爬蟲是什麼?Python爬蟲是什麼?Python爬蟲是由Python程序開發的網絡爬蟲(webspider,webrobot),是按照一定規則自動抓取全球資訊網信息的程序或腳本。為什麼需要用爬蟲?你可以想像一個場景:你在微博上崇拜一個名人,被他的微博迷住了。你要把他這十年微博裡的每一句話都摘抄下來。這個時候你會怎麼做?手動上Ctrl+C和Ctrl+V?這個方法是對的。在數據量很小的情況下我們還是可以這樣做的,但是在數據數千的情況下你還是要這樣做嗎?爬蟲技術可以輕鬆解決問題。
  • 如何在python語言代碼實現間隔加減法
    有這麼一個場景:0到100範圍,當是偶數時,就相加;若為奇數,就相減0-1+2-3+4-5+6-7+8-9+10……+98-99+100下面利用實例實現這個場景:操作步驟:1、打開Visual Studio工具,新建
  • 代碼跑得慢甩鍋Python?手把手教你如何給代碼提速30%
    其實某個特定程序(無論使用何種程式語言)的運行速度是快還是慢,在很大程度上取決於編寫該程序的開發人員自身素質,以及他們編寫優化而高效代碼的能力。Medium上一位小哥就詳細講了講如何讓python提速30%,以此證明代碼跑得慢不是python的問題,而是代碼本身的問題。