1. 程式人生 > >【爬蟲】Scrapy爬蟲框架教程-- 抓取AJAX非同步載入網頁

【爬蟲】Scrapy爬蟲框架教程-- 抓取AJAX非同步載入網頁

前一段時間工作太忙一直沒有時間繼續更新這個教程,最近離職了趁著這段時間充裕趕緊多寫點東西。之前我們已經簡單瞭解了對普通網頁的抓取,今天我就給大家講一講怎麼去抓取採用Ajax非同步加的網站。

工具和環境

  1. 語言:python 2.7
  2. IDE: Pycharm
  3. 瀏覽器:Chrome
  4. 爬蟲框架:Scrapy 1.3.3

什麼是AJAX?

AJAX即“Asynchronous Javascript And XML”(非同步JavaScript和XML),是指一種建立互動式網頁應用的網頁開發技術。

AJAX = 非同步 JavaScript和XML(標準通用標記語言的子集)。

AJAX 是一種用於建立快速動態網頁的技術。

通過在後臺與伺服器進行少量資料交換,AJAX 可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。

兩個Chrome外掛

Toggle JavaScript

JSON-handle

分析過程

分析頁面是否採用AJAX

上次我們拿了豆瓣當做例子,剛好我發現了豆瓣有AJAX非同步載入的頁面,這次我們就不換了,還拿豆瓣做例子。(逃
首先我們打開豆瓣電影分類排行榜 - 動作片欄目。

開啟過後你有沒有發現什麼不一樣的地方呢?如果你的網速慢你會發現下面的電影資訊是在網頁別的部分出現後才慢慢出現的,試著把介面往下滑會不斷有新的電影資訊更新出來。
遇到這種情況初步就可以認定這個頁面是採用AJAX非同步載入的,你也可以通過右鍵檢視網頁原始碼來鑑別。比如說你右鍵檢視原始碼ctrl+f搜尋這個殺手不太冷這幾個字,你會發現原始碼裡沒有。


上面的方法雖然能用,但是總感覺有點笨。還記得上面推薦的那個chrome外掛Toggle JavaScript嗎?

安好這個外掛它就會出現在chrome瀏覽器的右邊,試著輕輕點一下。

我的天吶!這麼神奇嗎?!剛才的電影資訊都不見了!還記得AJAX的介紹嗎?AJAX = 非同步 JavaScript和XML。當我們點選了外掛就代表這個我們封禁了JavaScript,這個頁面裡的JavaScript程式碼無法執行,那麼通過AJAX非同步載入而來的資訊當然就無法出現了。通過這種方法我們能快速精確地知道哪些資訊是非同步載入而來的。

如何抓取AJAX非同步載入頁面

對於這種網頁我們一般會採用兩種方法:

  1. 通過抓包找到AJAX非同步載入的請求地址;
  2. 通過使用PhantomJS等無頭瀏覽器執行JS程式碼後再對網頁進行抓取。

通常情況下我會採用第一種方法,因為使用無頭瀏覽器會大大降低抓取效率,而且第一種方法得到的資料格式往往以Json為主,非常乾淨。在這裡我只講解第一種方法,第二種方法作為爬蟲的終極武器我會在後續的教程中進行講解。
回到我們需要抓取的頁面,還記得我說過頁面的一個細節嗎,下拉更新。進入頁面後我們按F12開啟chrome瀏覽器的開發者工具選擇Network,然後實現一次下拉更新。

你會在Network裡發現一個Response為Json格式的請求,仔細看看Json裡的內容你會明白這些都是網頁上顯示的電影資訊。右鍵該請求地址選擇Open Link in New Tab,如果你裝了JSON-handle外掛你會以下面這種更友好的方式檢視這個Json串。

接著再讓我們看一該請求的Header資訊。

首先我們可以看出這是一個get請求,多看幾個下拉請求的地址後你會發現地中的start=xxx在不斷變化,每次增加20。所以我們只用更改這個引數就可以實現翻頁不斷獲取新資料(修改其他的引數也會有不同的效果,這裡就不一一細說了,留給大家慢慢地探索)。
spider程式碼如下:

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

30

31

32

33

34

35

36

37

38

39

40

# -*- coding: utf-8 -*-

# @Time : 2017/4/9 14:32

# @Author : woodenrobot

import re

import json

from scrapy import Request

from scrapy.spiders import Spider

from scrapyspider.items import DoubanMovieItem

class DoubanAJAXSpider(Spider):

name = 'douban_ajax'

headers = {

'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36',

}

def start_requests(self):

url = 'https://movie.douban.com/j/chart/top_list?type=5&interval_id=100%3A90&action=&start=0&limit=20'

yield Request(url, headers=self.headers)

def parse(self, response):

datas = json.loads(response.body)

item = DoubanMovieItem()

if datas:

for data in datas:

item['ranking'] = data['rank']

item['movie_name'] = data['title']

item['score'] = data['score']

item['score_num'] = data['vote_count']

yield item

# 如果datas存在資料則對下一頁進行採集

page_num = re.search(r'start=(\d+)', response.url).group(1)

page_num = 'start=' + str(int(page_num)+20)

next_url = re.sub(r'start=\d+', page_num, response.url)

yield Request(next_url, headers=self.headers)

在Scrapy工程檔案的spiders裡寫好爬蟲檔案後在settings.py所在的目錄下開啟終端執行以下程式碼就能輸出相應的電影資料。

1

scrapy crawl douban_ajax -o douban_movie.csv

結尾

整片文章主要以介紹思路為主,抓取的站點也只是做示範內容並不重要。授之以魚不如授之以漁,希望大家可以從這篇教程裡學到解決問題的方法與思路。: )