一只小爬蟲(轉)


我還年輕 , 我渴望上路 ...
                                                                      - <在路上>

引子


當Google創始人用python寫下他們第一個簡陋的爬蟲, 運行在同樣簡陋的服務器上的時候 ;
很少有人能夠想象 , 在接下的數十年間 , 他們是怎樣地顛覆了互聯網乃至於人類的世界 ;

今天 , 我們謹以一只小小的python爬蟲 , 作為我們的第一個編程作品 ;紀念並緬懷那個從python開始征途的偉大搜索引擎


注 : 上圖為Google的最初機房

預習材料


* python科普
* 易百python教程
* 笨方法學python
* 兩個小時學會python 作者 : 劉鑫
* Python 2.7 官方教程 中英文對照版本
* 正則表達式
* [英文] codecademy python 教程

課前准備


python : 我們最愛的編程語言

進入pyhon官網,選擇你所需要的版本,進行下載安裝。

python安裝完畢之后,會在開始菜單的python中,看到python幫助手冊。
幫助手冊可以作為案頭書,幫助我們快速查找。

如下圖 :我們對with 語句不熟悉,就可以實用幫助手冊的索引,快速查到相應的文檔。


ulipad : python代碼編輯器


ulipad 是一個很好用的python編輯器。跨平台,使用wxPython 編寫。

作者,limodou 。

我們從源碼進行安裝。

首先,安裝:

    * comtypes
    * wxPython

然后,下載ulipad

解壓后運行ulipad.pyw

ulipad提供了代碼的編輯,提示,運行,調試多種功能。


easy_install :python的包管理命令


setuptools 是python的包管理器 , 對應的命令是 easy_install 。

什么 , 你存在了這么多年還不知道什么叫做 “包管理”  !!!

包管理 就是 360的軟件管家 !!!

它可以幫我們 安裝 , 更新 軟件(或 代碼庫)。

下載腳本 ez_setup.py , 安裝 easy_install

windows用戶按 Window鍵 + R , 輸入cmd打開命令行窗口

setuptools 用法如下 :

     * 安裝模塊 :
        easy_install 包的名稱

    * 強制 更新/重裝 python的模塊 :
        easy_install -U 包的名稱

requests : for Humans 的 網絡庫


requests是一個github[注1]上排名前100名的項目。

官方的文檔 在自己首頁昭告天下 :

    Requests : HTTP for Humans

於是我意識到 , 這貨是為地球人准備的網絡庫。我們用它來在python中讀取網頁。

先切換到easy_install的安裝目錄中 , 然后執行 :
easy_install requests

如圖:  


wget : 命令行的下載工具



wget是Linux中的下載工具。我們也可以在windows上使用它。

首先 , 下載wget的windows版本。

然后 , 將文件解壓到C:\WINDOWS下,就可以直接在命令行中使用wget。

下面我們用wget下載一個我們即將用到的python模塊。

在終端下:
wget http://school-src.42qu.com/1_spider/extract.py
即可。

firebug: 前端工程師的神器


Firebug是Firefox的插件 , 前端工程師的神器 。

記得用 Firefox安裝 , 親。

Firebug有多個控制面板,常用的有html,net ,console。

使用html面板我們可以查看整個dom的文檔樹。


通過net面板我們可以查看到http的請求。


爬蟲是什么?


有網絡的地方就有爬蟲,爬蟲英文名稱spider,有時也叫它機器人(bot)。它是用來抓取網站數據的程序。

比如: 我們通過一段程序,定期去抓取類似美團,拉手網上的數據,將這些信息存儲到數據庫里,然后加上展示頁面,一個團購導航站就問世了。

毫無疑問,爬蟲是很多網站的初期數據來源。

先不說,google,百度這樣的以爬蟲起家的搜索引擎,就連豆瓣這樣的文藝小清新網站,也需要爬蟲去抓取圖書,唱片的基本信息。



今天我們就以 落網 為例,來實現一個下載mp3的小爬蟲。

首先, 右鍵點擊網頁上的元素,用Firebug的inspect工具審查元素。


我們發現落網的歌曲是通過一個<iframe>標簽內嵌一個flash的播放器來播放的。

於是,我們將iframe中的src( http://www.luoo.net/radio/radio395/mp3.xml)提取出來




新開一個頁面,打開鏈接,一下子好清爽,頁面上只有一個播放器了,而我們所要的歌曲名和下載地址也都在這個播放器中。


繼續使用firebug,將panel切換到Net。


因為剛才我們瀏覽頁面的時候,已經訪問過395,數據被瀏覽器緩存,刷新的時候就看不到全部請求。

我們將網址的395 換成394

刷新 http://www.luoo.net/radio/radio394/mp3.xml

Firebug的NET標簽中中列出了所有的請求。其中有一個叫做mp3.xml的鏈接。


新標簽頁打開,沒錯,這就是我們要找的東西。



打開這個xml頁面,其中是一個個

<song id="01" path=" http://ftp.luoo.net/radio/radio395/01.mp3" title="小木船"/>

這種標簽。 path 和title就是所需的數據。

但總不能這么手工下載吧。

爬蟲代碼,我來了 ^_^

不過在此之前,請你先認真閱讀預習材料,對python的語言有個基本的認識。

爬蟲代碼


首先,下載一個extract庫文件

在同一層目錄下用ulipad編輯下面的代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#! /usr/bin/env python
#coding=utf-8
  
import requests
from os.path import dirname, abspath
from extract import extract, extract_all
import re
RE_CN = re. compile (ur '[\u4e00-\u9fa5]+' )
PREFIX = dirname(abspath(__file__))
  
with open ( "%s/down.bat" % PREFIX, "w" ) as down:
     for i in xrange ( 1 , 396 ):
         for url in (
             'http://www.luoo.net/radio/radio%s/mp3.xml' % i,
             'http://www.luoo.net/radio/radio%s/mp3player.xml' % i
         ):
  
             r = requests.get(url)
             print url
             if r.status_code = = 200 :
                 for path, name in zip (
                     extract_all( 'path="' , '"', r.content),
                     extract_all('title="', '"' , r.content)
                 ):
                     if RE_CN.match(name.decode( 'utf-8' , 'ignore' )):
                         down.write( 'wget %s -O "%s/%s.mp3"\n' % (
                            path,PREFIX,name.decode( 'utf-8' ,
                             "ignore" ).encode( "gb18030" , "ignore" )))
                 break

建議大家用ulipad新建文檔,手寫一遍代碼!!!

再強調一遍, 手寫!!!不要復制粘貼!!!

代碼分析


因為我們的目的是下載落網上的所有中文歌曲。所以這里要做的工作主要分為三個部分。
首先,我們要對目標網址發出請求,獲取它的反饋。這里就是requests這個庫的作用了。
1
2
r = requests.get(url)
      if r.status_code = = 200 :
使用get方法,我們得到一個requests對象,如果status_code == 200 說明請求成功。

接下來就是分析返回值了。

這里用到了一個extract_all函數,它可以遍歷整個返回文檔,返回一個列表,里面包含我們提供的兩個參數的中間部分字符串。

extract_all('path="', '"', r.content),

獲取到值之后,我們就要對值進行一下過濾了。因為我們只想獲得中文的歌曲。

這里就用到了正則表達式:
1
RE_CN.match(name.decode( 'utf-8' , 'ignore' ))

它會對匹配中文字符串,如果是中文,我們就把它寫到文件中。

正則表達式 是 程序員 的 基本功 , 請認真閱讀 Python正則表達式操作指南

在寫文件這一步,我們還做了一個處理
1
PREFIX = dirname(abspath(__file__))

其中 __file__ 是python的一個內置變量。表示的是當前運行的文件名。
通過 dirname(abspath(__file__))我們就可以把爬蟲文件和將要下載的mp3文件都在同一個目錄下。

運行爬蟲


在ulipad中點擊運行,我們的爬蟲就開始爬動了。因為它還很小,還不懂什么多線程,所以速度還比較慢,稍等片刻后,我們會生成一個down.bat文件。
雙擊這個bat文件,我們的MP3就開始下載了。


課后練習


自己實現 extact 和 extact_all  函數
下載中關村壁紙站的所有壁紙

擴展閱讀


The Hitchhiker’s Guide to Python!

注:
1.github是全世界最大的程序員代碼版本控制網站


免責聲明!

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



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