用PySpider蒐集2017年高校招生章程

我的認爲PySpider是一個十分容易上手並且功能強大的Python爬蟲框架。支持多線程爬取、JS動態解析、出錯重試、定時爬取等等的功能。最重要的是,它經過web提供了可操做界面,使用很是人性化。
最近因爲工做的緣由,秉承這服務廣大高考考生和家長的態度ヾ(≧O≦)〃嗷~,我搜集了2017年2000多所高校的高校招生章程。css

安裝PySpiderhtml

首先先要安裝pip跟phantomjs:python

1web

sudo apt install python-pip phantomjsjson

phantomjs是一個基於webkit內核的無界面瀏覽器,提供JavaScript API接口。在PySpider中用於JS動態解析。瀏覽器

以後能夠用pip直接安裝PySpider:網絡

1多線程

sudo pip install pyspider併發

經過如下指令就能夠啓動PySpider啦:框架

1

pyspider all

打開瀏覽器訪問http://localhost:5000能夠看到web界面:

以後點擊Create能夠新建一個爬蟲項目:

以後就能夠看到一個爬蟲操做的頁面:

頁面分開爲兩半。左半邊是爬蟲結果預覽,右半邊是爬蟲代碼編寫區域。
左側上半部分是爬蟲的每一個網絡請求的解析。下半部分是爬蟲頁面瀏覽。
最下面有5個按鈕:
enable css selector helper按鈕:點擊它啓動css selector helper。用鼠標點擊頁面的元素能夠很方便地生成該元素的css選擇器表達式;
web: 點擊能夠查看抓取的頁面的實時預覽圖;
html: 點擊能夠查看抓取頁面的 HTML 代碼。
follows: 若是這一層抓取方法中又新建了網頁請求,那麼接下來的請求就會出如今 follows 裏。
messages: 一個控制檯,用於顯示爬蟲輸出的信息。

分析下網站吧
咱們要爬的是教育部陽光高考信息公開平臺:http://gaokao.chsi.com.cn/zsgs/zhangcheng/listVerifedZszc--method-index,lb-1,start-0.dhtml
一共有28頁'start-'後邊接的是頁數的編號。

因此我打算這樣寫on_start方法來開始這條爬蟲:

1

2

3

4

5

6

def on_start(self):

    while self.page_num < self.total_num:

        url = self.base_url + str(self.page_num*100)+'.dhtml'

        print(url)

        self.crawl(url,callback = self.index_page)

        self.page_num = self.page_num + 1

先定義頁碼前的地址,以後定義頁碼。crawl方法新建了請求以後把返回的結果傳給callback參數裏的方法。
按下save保存,再按run試着運行一下吧:

能夠看到follow按鈕上面出現了28的數字,這就是咱們新建的28個頁面請求啦。而後咱們點擊左側第一個綠色箭頭,能夠繼續爬取第一頁這個頁面。

裏邊灰色字體的是暫時沒有公佈2017年招生章程的學校,而咱們須要選定藍色字體的學校以及其連接。點擊html查看其網頁源碼:

能夠看到咱們要選擇td下面的沒有style="color:gray"這個屬性的a標籤。
那麼css表達式能夠這麼寫:td a:not([style="color:gray"])[target="_blank"]
補充index_page方法:

1

2

3

def index_page(self, response):

    for each in response.doc('td a:not([style="color:gray"])[target="_blank"]').items():

        self.crawl(each.attr.href, callback=self.detail_page)

pyspider爬取的內容經過回調的參數response返回,response有多種解析方式。
一、response.json用於解析json數據
二、response.doc返回的是PyQuery對象
三、response.etree返回的是lxml對象
四、response.text返回的是unicode文本
五、response.content返回的是字節碼
response.doc()實際上是調用了 PyQuery框架,用 CSS 選擇器獲得每個公佈了2017年招生章程的連接,而後從新發起新的請求,回調函數就是 detail_page。修改完save以後run,就新建了80個請求了:

點第一個請求就能夠進入北京大學這幾年招生章程的頁面啦:

咱們想要的是第一個2017年的章程,這時候點擊enable css selector helper按鈕,以後點一下2017的章程連接,能夠看到它給咱們的css選擇器表達式選定了以前全部的章程:

不過沒關係( ̄_, ̄ ),2017年的章程老是在第一個,因此咱們能夠只選定第一個給回調函數處理。

1

2

3

def detail_page(self, response):

    new_constitution = next(response.doc('td > a').items())

    self.crawl(new_constitution.attr.href, callback=self.constitution_page)

response.doc()方法返回的其實是個選擇器對象而不是列表。因此不能用列表切片操做,用第一個next能夠返回選擇器裏的第一個元素,那就是2017年的章程啦。以後給constitution_page方法處理。
接下來就到了簡章內容的頁面啦。

1

2

3

4

5

6

7

8

9

def constitution_page(self,response):

    i = list(response.doc('p[style="margin-left:10px"] > a').items())[1].text()

    os.chdir("/home/imquanquan/constitution/")

    with open(i + u'2017年招生章程.html', 'w') as f:

        f.write('''<head>

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        </head>''')

        for each in list(response.doc('p').items())[3:]:

            f.write(str(each))

咱們選定了全部的p標籤,從第四個開始就是章程的正文,而後寫入文件完成編寫爬蟲任務。ヽ(✿゚▽゚)ノ

記得save以後回到Dashboaed主頁面。把項目的status改成running,按run就能夠開始爬爬爬啦。

是否是感受速度有點慢?rate/burst選項能夠調節速度的。rate是指每秒執行多少個請求,burst是設置併發數,如 rate/burst = 1/3 這個意思是爬蟲每1秒執行一個請求,可是前三個任務會同時執行,不會等1秒,第四個任務會等1秒再執行。默認的1/3速度比較慢。能夠調到比較高,而burst不能小於rate。

相關文章
相關標籤/搜索