scrapy入門實戰練習(三)----抓取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

這個插件可以幫助我們快速直觀地檢測網頁裏哪些信息是通過AJAX異步加載而來的,具體怎麼用,下面會詳細講解。
chrome商店下載地址:chrome.google.com/webst(Ps:打不的小夥伴自行百度搜索國內提供chrome插件下載的網站離線安裝)

JSON-handle

這個插件可以幫我們格式化Json串,從而讓我們以一個更友好的方式查看Json內的信息。 chrome商店下載地址:chrome.google.com/webst(Ps:打不的小夥伴自行百度搜索國內提供chrome插件下載的網站離線安裝)

分析過程

分析頁面是否採用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。所以我們只用更改這個參數就可以實現翻頁不斷獲取新數據(Ps:修改其他的參數也會有不同的效果,這裏就不一一細說了,留給大家慢慢地探索)。 spider代碼如下:

# -*- 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所在的目錄下打開終端運行以下代碼就能輸出相應的電影數據。

scrapy crawl douban_ajax -o douban_movie.csv

代碼Github地址: github.com/Wooden-Robot

結尾

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章