1. 程式人生 > >(python解析js)scrapy結合ghost抓取js生成的頁面,以及js變數的解析

(python解析js)scrapy結合ghost抓取js生成的頁面,以及js變數的解析

現在頁面用ajax的越來越多, 好多程式碼是通過js執行結果顯示在頁面的(比如:http://news.sohu.com/scroll/,搜狐滾動新聞的列表是在頁面請求時由後臺一次性將資料渲染到前臺js變數newsJason和arrNews裡面的,然後再由js生成div和li,故要想或得結果必須要解析執行js), 所以在scrapy抓取過程中就需要通過一箇中間件來執行這個js程式碼。

scrapy 本身不能作為js engine,這就導致很多js生成的頁面的資料會無法抓取到,因此,一些通用做法是使用webkit或基於webkit的庫。

Ghost是一個python的webkit客戶端,基於webkit的核心,使用了pyqt或者pyside的webkit實現。

安裝:

1.安裝sip(pyqt依賴):
wget http://sourceforge.net/projects/pyqt/files/sip/sip-4.14.6/sip-4.14.6.tar.gz
tar zxvf sip-4.14.6.tar.gz
cd sip-4.14.6
python configure.py
make
sudo make install
2.安裝pyqt
wget http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.10.1/PyQt-x11-gpl-4.10.1.tar.gz 
tar zxvf PyQt-x11-gpl-4.10
.1.tar.gz cd PyQt-mac-gpl-4.10.1 python configure.py make sudo make install 3.安裝Ghost git clone git://github.com/carrerasrodrigo/Ghost.py.git cd Ghost.py sudo python setup.py install

scrapy使用ghost:

1.開發downloader middleware (webkit_js.py)

from scrapy.http import Request,FormRequest,HtmlResponse
import
JsSpider.settings from ghost import Ghost class WebkitDownloader(object): def process_request(self,request,spider): if spider.name in JsSpider.settings.WEBKIT_DOWNLOADER: if(type(request) is not FormRequest): ghost = Ghost() session = ghost.start() session.open(request.url) result,resource = session.evaluate('document.documentElement.innerHTML') #保留會話到爬蟲,用以在爬蟲裡面執行js程式碼 spider.webkit_session = session renderedBody = str(result.toUtf8()) #返回rendereBody就是執行了js後的頁面 return HtmlResponse(request.url,body=renderedBody)

2.scrapy配置

在scrapy的settings.py中加入:

#which spider should use webkit
WEBKIT_DOWNLOADER = ['spider_name']
DOWNLOADER_MIDDLEWARES = {
  #'JsSpider.middleware.rotate_useragent.RotateUserAgentMiddleware': 533,
    'JsSpider.middleware.webkit_js.WebkitDownloader': 543,
}

其中
JsSpider.middleware.rotate_useragent.RotateUserAgentMiddleware為user agent池

# -*-coding:utf-8-*-
from scrapy import log
"""避免被ban策略之一:使用useragent池。
使用注意:需在settings.py中進行相應的設定。
"""
import random
from scrapy.downloadermiddlewares.useragent import UserAgentMiddleware

class RotateUserAgentMiddleware(UserAgentMiddleware):
    def __init__(self, user_agent=''):
        self.user_agent = user_agent
    def process_request(self, request, spider):
        ua = random.choice(self.user_agent_list)
        if ua:
            #顯示當前使用的useragent
            #print "********Current UserAgent:%s************" %ua
            #記錄
            log.msg('Current UserAgent: '+ua, level=log.INFO)
            request.headers.setdefault('User-Agent', ua)
    #the default user_agent_list composes chrome,I E,firefox,Mozilla,opera,netscape
    #for more user agent strings,you can find it in http://www.useragentstring.com/pages/useragentstring.php
    user_agent_list = [
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 "
        "(KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 "
        "(KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 "
        "(KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 "
        "(KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 "
        "(KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 "
        "(KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 "
        "(KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 "
        "(KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 "
        "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 "
        "(KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"
       ]

3.spider中解析js

from scrapy.spiders import Spider
from scrapy.selector import Selector
from scrapy.http import Request
from JsSpider.items import JsSpiderItem

#import sys
#reload(sys)
#sys.setdefaultencoding('utf-8')

class JsSpider(Spider):
    def __init__(self):
        self.webkit_session = None
    name = "js"
    #download_delay = 3
    allowed_domains = ["news.sohu.com"]
    start_urls = [
        "http://news.sohu.com/scroll/"
        ]

    def parse(self, response):
        items = []
        newsJason = self.webkit_session.evaluate('newsJason')   #獲得js物件
        arrNews = self.webkit_session.evaluate('arrNews')       #獲得js物件
        print type(newsJason)
        print type(arrNews)

        newsJason = newsJason[0]
        arrNews = arrNews[0]

        category =[v for k,v in newsJason.iteritems()][0]

        for i in range(len(category)):
            for j in range(len(category[i])):
                category[i][j]=str(category[i][j])

        for i in range(len(arrNews)):
            for j in range(len(arrNews[i])):
                arrNews[i][j]=str(arrNews[i][j])
        #ghost解析js返回的結果一般為QString物件,轉換起來比較麻煩,特別是複雜的資料結果,層層巢狀都算QString型別,還有編碼問題,後面資料的格式化,有空在弄吧
        print category
        print arrNews

        return items

說明:

scrapy請求的頁面通過中介軟體執行js後返回response給spider,此時的reponse的js變數裡面有我們需要的資料,再通過spider初始化的ghost會話webkit_session執行js變數解析,使用了evaluate(javascript)函式,要獲得js變數arrNews的值,只需要執行self.webkit_session.evaluate(‘arrNews’)

相關推薦

python解析jsscrapy結合ghostjs生成頁面以及js變數解析

現在頁面用ajax的越來越多, 好多程式碼是通過js執行結果顯示在頁面的(比如:http://news.sohu.com/scroll/,搜狐滾動新聞的列表是在頁面請求時由後臺一次性將資料渲染到前臺js變數newsJason和arrNews裡面的,然後再由js生

python解析jsselenium結合phantomjsjs生成頁面

,有些網頁是在載入時動態建立HTML內容,只要在js程式碼完全執行完後才會顯示最終結果。如果用傳統的方法抓取頁面,就只能獲得js程式碼執行之前頁面上的內容。 要解決這個問題有兩種方法: 1.直接從js程式碼中抓取資料(執行js程式碼,解析js變數)。

重修課程day1python基礎1

width 學java 復雜 符號 硬件組成 常見 高級 clas c語言: 一 什麽是計算機   1 計算機就是由一堆硬件組成的一個機器。   2 硬件的分類:    CPU:猶如人類的大腦,運行著需要運行的程序。     內存:將 CPU要運行的內容從硬盤中讀取出來,然

重修課程day2python基礎2

類型 a* 代碼 false utf-8 意思 bytes 使用 byte 一 字符串格式化   占位符 %s和%d %s是屬於字符串的占位符,而%d是屬於數字類型的占位符 #占位符 %s %d # a="我叫%s,年齡%d,就是一個%s"%("alex",84,"sb

urlparse模塊python模塊

urlparse python一、urlparse模塊簡介 urlparse模塊主要是把url拆分為6部分,並返回元組。並且可以把拆分後的部分再組成一個url。主要有函數有urljoin、urlsplit、urlunsplit、urlparse等。二、urljoin函數使用 urljoin主要是拼

yum無法安裝軟件python版本問題

imp led pos yourself there round org share req 遇到如下問題:[root@sa yum.repos.d]# yum repolistThere was a problem importing one of the Python

Python-turtle庫知識小結python繪圖工具

thead color 運行 入庫 logs erl pen 顏色 word   turtle:海龜(海龜庫) Turtle庫是Python語言中一個很流行的繪制圖像的函數庫 使用之前需要導入庫:import turtle ? turtle.setup(wid

模塊、類和對象python學習筆記

python 類 模塊 對象 模塊、類和對象 1.字典,記住鍵值對的概念,記住從鍵值對 mystuff = {‘apple‘:"I am apples"} print mystuff[‘apple‘] 2.模塊 ‘‘‘ 模塊 1.模塊是包含函數和變量的文件 2.模塊這個

數據預處理Python scikit-learn

距離度量 sklearn 神經網絡 效果 binary load roc maxscale 可能 在機器學習任務中,經常會對數據進行預處理.如尺度變換,標準化,二值化,正規化.至於采用哪種方法更有效,則與數據分布和采用算法有關.不同算法對數據的假設不同,可能需要不同的變換,

使用scrapy框架進行伯樂線上所有文章

這是跟著相關視訊學習進行的程式碼,(一)學習思路的程式碼在整個完整程式碼中存在一部分,如果看到這些內容或思路有不懂的給我下面部落格留言。完整程式碼github地址:https://github.com/spider-liu/jobbole-,主要是作為學習交流之用。 一、scrapy框架簡介

2.1 The Python Interpreterpython解釋器

技術分享 python 告訴 使用方法 代碼 code 項目 pri src 2.1 The Python Interpreter(Python解釋器) Python是一門解釋性語言。Python的解釋器一次只能運行一個命令。標準的Python解釋器環境可以用通過輸入pyt

python爬蟲時如何知道是否代理ip偽裝成功

通過請求  http://httpbin.org/get   獲得類似以下資訊: { "args": {}, "headers": { "Accept": "text/html,application/xhtml+xml,applicat

[後端開發]支付寶支付介面除錯 Python v3.6

寫在前面:     講真,一開始接到這個任務我是拒絕的。因為支付寶官方沒有提供Python的SDK環境,只有JAVA/PHP/.NET三種語言的SDK,這意味著簽名&驗籤、HTTP介面請求等操作全都要自己手動實現,就算支付寶提供了簽名、驗籤的演算法說明,但僅靠它的

【LeetCode】754. Reach a Number 解題報告Python & C++

作者: 負雪明燭 id: fuxuemingzhu 個人部落格: http://fuxuemingzhu.cn/ 目錄 題目描述 題目大意 解題方法 數學 日期 題目

【LeetCode】947. Most Stones Removed with Same Row or Column 解題報告Python & C++

作者: 負雪明燭 id: fuxuemingzhu 個人部落格: http://fuxuemingzhu.cn/ 目錄 題目描述 題目大意 解題方法 並查集 日期 題

爬蟲不過如此python 詳細篇

網路爬蟲(又被稱為網頁蜘蛛,網路機器人,在FOAF社群中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取全球資訊網資訊的程式或者指令碼。 爬蟲的本質就是一段自動抓取網際網路資訊的程式,從網路獲取感興趣的資訊,抓取對於我們有價值的資訊,爬蟲技術是大資料和雲端計算的基礎。 爬蟲的實現可認為是模擬

模擬RSA雙向驗證並且實現DES加密以及MD5校驗過程python程式碼實現

要求如下:            (1)A,B兩端各生成公鑰金鑰對(PA,SA), 金鑰對(PB,SB)。            (2)A端生成隨機數N1,用B的公鑰PB加

順序表python語言描述

首先我們說線性表(順序表和連結表的統稱): 線性表是什麼?它是某類元素的一個集合,而且它還表示這個元素集合中各種元素的一種順序關係,對於兩種模式的線性表,區別在於這種關係的表示上的不同。 順序表:將元素

LeetCode題目--有效的數獨python/Java實現

題目 判斷一個 9x9 的數獨是否有效。只需要根據以下規則,驗證已經填入的數字是否有效即可。 數字 1-9 在每一行只能出現一次。 數字 1-9 在每一列只能出現一次。 數字 1-9 在每一個以

【洛谷2152】[SDOI2009] SuperGCDPython好題

點此看題面 大致題意: 給你兩個長度≤10000\le10000≤10000的正整數,讓你求它們的gcdgcdgcd。 Python​ 高精請繞道。 這題的正解應該是Python。 對於這種高精題,肯