當前位置:
首頁 > 知識 > 美劇迷是如何使用Python的

美劇迷是如何使用Python的

點擊上方

Python開發

」,選擇「置頂公眾號」


關鍵時刻,第一時間送達!



一直有愛看美劇的習慣,一方面鍛煉一下英語聽力,一方面打發一下時間。之前是能在視頻網站上面在線看的,可是自從廣電總局的限制令之後,進口的美劇英劇等貌似就不在像以前一樣同步更新了。但是,作為一個宅diao的我又怎甘心沒劇追呢,所以網上隨便查了一下就找到一個能用迅雷下載的美劇下載網站【天天美劇】,各種資源隨便下載,最近迷上的BBC的高清紀錄片,大自然美得不要不要的。


雖說找到了資源網站可以下載了,但是每次都要打開瀏覽器,輸入網址,找到該美劇,然後點擊鏈接才能下載。時間長了就覺得過程好繁瑣,而且有時候網站鏈接還會打不開,會有點麻煩。正好一直在學習Python爬蟲,所以今天就心血來潮來寫了個爬蟲,抓取該網站上所有美劇鏈接,並保存在文本文檔中,想要哪部劇就直接打開複製鏈接到迅雷就可以下載啦。



其實一開始打算寫那種發現一個 url ,使用 requests 打開抓取下載鏈接,從主頁開始爬完全站。但是,好多重複鏈接,還有其網站的 url 不是我想的那麼規則,寫了半天也沒有寫出我想要的那種發散式的爬蟲,也許是自己火候還不到吧,繼續努力。。。


後來發現,其電視劇鏈接都是在文章裡面,然後文章url後面有個數字編號,就像這樣的http://cn163.net/archives/24016/,所以機智的我又用了之前寫過的爬蟲經驗,解決方法就是自動生成url,其後面的數字不是可以變的嗎,而且每部劇的都是唯一的,所以嘗試了一下大概有多少篇文章,然後用range函數直接連續生成數來構造url。


但是很多 url 是不存在的,所以會直接掛掉,別擔心,我們用的可是 requests ,其自帶的 status_code 就是用來判斷請求返回的狀態的,所以只要是返回的狀態碼是404的我們都把它跳過,其他的都進去爬取鏈接,這就解決了 url 的問題了。


以下就是上述步驟的實現代碼。

  1. def

    get_urls

    (

    self

    ):

  2.    

    try

    :

  3.        

    for

    i

    in

    range

    (

    2015

    ,

    25000

    ):

  4.            base_url

    =

    "http://cn163.net/archives/"

  5.            url

    =

    base_url

    +

    str

    (

    i

    )

    +

    "/"

  6.            

    if

    requests

    .

    get

    (

    url

    ).

    status_code

    ==

    404

    :

  7.                

    continue

  8.            

    else

    :

  9.                self

    .

    save_links

    (

    url

    )

  10.    

    except

    Exception

    ,

    e

    :

  11.        

    pass


其餘的就進行的很順利了,網上找到前人寫的類似的爬蟲,但是只是爬取一篇文章的,所以借鑒了一下其正則表達式。自己用了 BeautifulSoup 還沒有正則效果好,所以果斷棄了,學海無涯啊。但是效果也不是那麼理想,有一半左右的鏈接不能正確抓取,還需繼續優化。



編程派:下面的代碼中 reload(sys);sys.setdefaultencoding("utf-8") 的做法是不推薦的,容易產生錯誤。

  1. #  -*- coding:utf-8 -*-

  2. import

    requests

  3. import

    re

  4. import

    sys

  5. import

    threading

  6. import

    time

  7. reload

    (

    sys

    )

  8. sys

    .

    setdefaultencoding

    (

    "utf-8"

    )

  9. class

    Archives

    (

    object

    ):

  10.    

    def

    save_links

    (

    self

    ,

    url

    ):

  11.        

    try

    :

  12.            data

    =

    requests

    .

    get

    (

    url

    ,

    timeout

    =

    3

    )

  13.            content

    =

    data

    .

    text

  14.            link_pat

    =

    ""(ed2k://|file|[^"]+?.(Sd+)(Ed+)[^"]+?1024Xd{3}[^"]+?)""

  15.            name_pat

    =

    re

    .

    compile

    (

  16.                r

    "<h2 class="entry_title">(.*?)</h2>"

    ,

    re

    .

    S

    )

  17.            links

    =

    set

    (

    re

    .

    findall

    (

    link_pat

    ,

    content

    ))

  18.            name

    =

    re

    .

    findall

    (

    name_pat

    ,

    content

    )

  19.            links_dict

    =

    {}

  20.            count

    =

    len

    (

    links

    )

  21.        

    except

    Exception

    ,

    e

    :

  22.            

    pass

  23.        

    for

    i

    in

    links

    :

  24.            links_dict

    [

    int

    (

    i

    [

    1

    ][

    1

    :

    3

    ])

    *

    100

    +

  25.                       int

    (

    i

    [

    2

    ][

    1

    :

    3

    ])]

    =

    i  

    # 把劇集按s和e提取編號

  26.        

    try

    :

  27.            

    with

    open

    (

    name

    [

    0

    ].

    replace

    (

    "/"

    ,

    " "

    )

    +

    ".txt"

    ,

    "w"

    )

    as

    f

    :

  28.                

    print

    name

    [

    0

    ]

  29.                

    for

    i

    in

    sorted

    (

    list

    (

    links_dict

    .

    keys

    ())):

     

    # 按季數+集數排序順序寫入

  30.                    f

    .

    write

    (

    links_dict

    [

    i

    ][

    0

    ]

    +

    "
    "

    )

  31.            

    print

    "Get links ... "

    ,

    name

    [

    0

    ],

    count

  32.        

    except

    Exception

    ,

    e

    :

  33.            

    pass

  34.    

    def

    get_urls

    (

    self

    ):

  35.        

    try

    :

  36.            

    for

    i

    in

    range

    (

    2015

    ,

    25000

    ):

  37.                base_url

    =

    "http://cn163.net/archives/"

  38.                url

    =

    base_url

    +

    str

    (

    i

    )

    +

    "/"

  39.                

    if

    requests

    .

    get

    (

    url

    ).

    status_code

    ==

    404

    :

  40.                    

    continue

  41.                

    else

    :

  42.                    self

    .

    save_links

    (

    url

    )

  43.        

    except

    Exception

    ,

    e

    :

  44.            

    pass

  45.    

    def

    main

    (

    self

    ):

  46.        thread1

    =

    threading

    .

    Thread

    (

    target

    =

    self

    .

    get_urls

    ())

  47.        thread1

    .

    start

    ()

  48.        thread1

    .

    join

    ()

  49.    

    if

    __name__

    ==

    "__main__"

    :

  50.    start

    =

    time

    .

    time

    ()

  51.    a

    =

    Archives

    ()

  52.    a

    .

    main

    ()

  53.    end

    =

    time

    .

    time

    ()

  54.    

    print

    end

    -

    start


完整版代碼,其中還用到了多線程,但是感覺沒什麼用,因為 Python 的 GIL 的緣故吧,看似有兩萬多部劇,本以為要很長時間才能抓取完成,但是除去 url 錯誤的和沒匹配到的,總共抓取時間20分鐘不到。搞得我本來還想使用 Redis 在兩台 Linux 上爬取,但是折騰了一番之後感覺沒必要,所以就這樣吧,後面需要更大數據的時候再去弄。


還有過程中遇到一個很折磨我的問題是文件名的保存,必須在此抱怨一下, txt 文本格式的文件名能有空格,但是不能有斜線、反斜線、括弧等。就是這個問題,一早上的時間都花在這上面的,一開始我以為是抓取數據的錯誤,後面查了半天才發現是爬取的劇名中帶有斜杠,這可把我坑苦了。





  • 作 者:肖豪-碼農網



  • 原文鏈接:http://www.codeceo.com/article/python-crawling-drama.html



  • Python開發整理髮布,轉載請聯繫作者獲得授權


【點擊成為Android大神】

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發 的精彩文章:

不想再被鄙視?那就看進來! 一文搞懂 Python 2 字元編碼
你用 Python 寫過哪些牛逼的程序/腳本?

TAG:Python開發 |