Scrapy+Selenium+Phantomjs的Demo

  前段時間學習了用Python寫爬蟲,使用Scrapy框架爬取京東的商品信息。商品詳情頁的價格是由js生成的,而通過Scrapy直接爬取的源文件中無價格信息。
  通過Selenium、Phantomjs便能實現。下面先介紹Phantomjs。
(我的博客原文地址:https://chaycao.github.io/2016/08/19/Scrapy-Selenium-Phantomjs/ 請多指教!)

Phantomjs

  作爲一個基於webkit內核的沒有UI界面的瀏覽器,大家不必被這個名字嚇到,以爲是很複雜的技術,其實只是一個瀏覽器啦。而其中的一些點擊、翻頁等操作則由代碼實現。Phantomjs提供javascript API接口,即我們可以通過js與webkit內核交互。
  只需通過Phantomjs test.js的命令就能成功訪問頁面,並將js生成後的內容下載下來。

// a phantomjs example
// test.js
var page = require('webpage').create();  //獲取操作dom或web網頁的對象
var fs = require('fs');                  //獲取文件系統對象,通過它可以操作操作系統的文件操作,包括read、write、move、copy、delete等。
phantom.outputEncoding="utf-8";
//通過page對象打開url鏈接,並可以回調其聲明的回調函數
page.open("http://chaycao.github.io", function(status) {   
if ( status === "success" ) {
    console.log("成功");
    fs.write('web.html',page.content,'w');
    } else {
    console.log("Page failed to load.");
}
phantom.exit(0);
}); 

  關於Phantomjs的詳細介紹可以參照這篇博文:http://blog.csdn.net/tengdazhang770960436/article/details/41320079

Selenium

  作爲一個用於Web應用程序測試的工具,其測試直接運行在瀏覽器中,框架底層使用JavaScript模擬真實用戶對瀏覽器的操作,從終端用戶的角度測試應用程序。將Selenium與Phantomjs聯繫起來,便是我們可以通過使用Selenium操作Phantomjs訪問網頁以獲得js生成後的網頁。

  在我看來,這裏Selenium的作用就像是Scrapy調用Phantomjs的中介。我也存有疑問:“Scrapy是否能直接調用Phantomjs?” 期望回覆

Scrapy使用Selenium

需要弄懂一個概念,下載中間件,可以閱讀下官方文檔http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/downloader-middleware.html

在settings.py加入

DOWNLOADER_MIDDLEWARES = {
    'jdSpider.middlewares.middleware.JavaScriptMiddleware': 543, #鍵爲中間件類的路徑,值爲中間件的順序
    'scrapy.downloadermiddlewares.useragent.UserAgentMiddleware':None, #禁止內置的中間件
}

第一行爲中間件的位置,需要與自己目錄對應,我的目錄是這樣的:
文件目錄

如果運行遇到robots.txt的問題,需要將settings.py中的

ROBOTSTXT_OBEY = False

下面貼上,自定義中間件的代碼:

from selenium import webdriver
from scrapy.http import HtmlResponse
import time

class JavaScriptMiddleware(object):

def process_request(self, request, spider):
    if spider.name == "jd":
        print "PhantomJS is starting..."
        driver = webdriver.PhantomJS() #指定使用的瀏覽器
        # driver = webdriver.Firefox()
        driver.get(request.url)
        time.sleep(1)
        js = "var q=document.documentElement.scrollTop=10000" 
        driver.execute_script(js) #可執行js,模仿用戶操作。此處爲將頁面拉至最底端。       
        time.sleep(3)
        body = driver.page_source
        print ("訪問"+request.url)
        return HtmlResponse(driver.current_url, body=body, encoding='utf-8', request=request)
    else:
        return

在spiders/jd.py中parse()方法接收到的response則是我們自定義中間件返回的結果。我們得到的便是js生成後的界面。

# -*- coding: utf-8 -*-
import scrapy

class JdSpider(scrapy.Spider):
    name = "jd"
    allowed_domains = ["jd.com"]
    start_urls = (
        'http://search.jd.com/Search?keyword=三星s7&enc=utf-8&wq=三星s7&pvid=tj0sfuri.v70avo',
    )

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