首頁  >  文章  >  web前端  >  Scrapy與scrapy-splash框架快速載入js頁面

Scrapy與scrapy-splash框架快速載入js頁面

小云云
小云云原創
2018-03-07 14:01:354021瀏覽

一、前言

我們在使用爬蟲程式爬取網頁時,一般對於靜態頁面的爬取是比較簡單的,之前寫過挺多的案例。但是對於使用js動態載入的頁面如何爬取呢?

對於動態js頁面的爬取有以下幾種爬取的方式:

  1. #透過selenium+phantomjs實作。

  • phantomjs是一個無頭瀏覽器,selenium是一個自動化測試的框架,透過無頭瀏覽器請求頁面,等待js加載,再透過自動化測試selenium取得數據。因為無頭瀏覽器非常消耗資源,所在效能方面有所欠缺。

  • Scrapy-splash框架:

    • #Splash作為js渲染服務,是基於Twisted和QT開發的輕量瀏覽器引擎,並提供直接的http api。快速、輕量的特點使其容易進行分散式開發。

    • splash和scrapy爬蟲框架融合,兩種互相相容的特點,抓取效率較好。

    二、Splash環境建置

    Splash服務是基於docker容器的,所以我們需要先安裝docker容器。

    2.1 docker安裝(windows 10 家用版)

    如果是win 10專業版或其他作業系統,都是比較好安裝的,在windows 10家用版安裝docker需要透過toolbox(需要最新的)工具安裝才行。

    關於docker的安裝,請參考文件:WIN10安裝Docker

    2.2 splash安裝

    docker pull scrapinghub/splash

    2.3 啟動Splash服務

    docker run -p 8050:8050 scrapinghub/splash

    Scrapy與scrapy-splash框架快速載入js頁面

    這個時候,打開你的瀏覽器,輸入192.168.99.100:8050你會看到出現了這樣的介面。

    Scrapy與scrapy-splash框架快速載入js頁面

    你可以在上圖紅色框框的地方輸入任意的網址,點擊後面的Render me! 來查看渲染之後的樣子

    2.4 安裝python的scrapy-splash包

    pip install scrapy-splash

    三、scrapy爬蟲載入js專案測試,以google news為例。

    由於業務需要爬取一些國外的新聞網站,如google news。但是發現居然是js程式碼。於是開始使用scrapy-splash框架,配合Splash的js渲染服務,取得資料。具體看如下程式碼:

    3.1 settings.py配置資訊

    # 渲染服务的urlSPLASH_URL = 'http://192.168.99.100:8050'# 去重过滤器DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'# 使用Splash的Http缓存HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'SPIDER_MIDDLEWARES = {    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
    }#下载器中间件DOWNLOADER_MIDDLEWARES = {    'scrapy_splash.SplashCookiesMiddleware': 723,    'scrapy_splash.SplashMiddleware': 725,    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
    }# 请求头DEFAULT_REQUEST_HEADERS = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    }# 管道ITEM_PIPELINES = {   'news.pipelines.NewsPipeline': 300,
    }

    3.2 items欄位定義

    class NewsItem(scrapy.Item):    # 标题
        title = scrapy.Field()    # 图片的url链接
        Scrapy與scrapy-splash框架快速載入js頁面_url = scrapy.Field()    # 新闻来源
        source = scrapy.Field()    # 点击的url
        action_url = scrapy.Field()

    3.3 Spider程式碼

    在spider目錄下,創建一個new_spider.py的文件,文件內容如下:

    from scrapy import Spiderfrom scrapy_splash import SplashRequestfrom news.items import NewsItemclass GoolgeNewsSpider(Spider):
        name = "google_news"
    
        start_urls = ["https://news.google.com/news/headlines?ned=cn&gl=CN&hl=zh-CN"]    def start_requests(self):
            for url in self.start_urls:            # 通过SplashRequest请求等待1秒
                yield SplashRequest(url, self.parse, args={'wait': 1})    def parse(self, response):
            for element in response.xpath('//p[@class="qx0yFc"]'):
                actionUrl = element.xpath('.//a[@class="nuEeue hzdq5d ME7ew"]/@href').extract_first()
                title = element.xpath('.//a[@class="nuEeue hzdq5d ME7ew"]/text()').extract_first()
                source = element.xpath('.//span[@class="IH8C7b Pc0Wt"]/text()').extract_first()
                Scrapy與scrapy-splash框架快速載入js頁面Url = element.xpath('.//img[@class="lmFAjc"]/@src').extract_first()
    
                item = NewsItem()
                item['title'] = title
                item['Scrapy與scrapy-splash框架快速載入js頁面_url'] = Scrapy與scrapy-splash框架快速載入js頁面Url
                item['action_url'] = actionUrl
                item['source'] = source            yield item

    3.4 pipelines.py代碼

    將item的數據,儲存到mysql資料庫。

    • 建立db_news資料庫

    CREATE DATABASE db_news
    • 建立tb_news表

    CREATE TABLE tb_google_news(
        id INT AUTO_INCREMENT,
        title VARCHAR(50),
        Scrapy與scrapy-splash框架快速載入js頁面_url VARCHAR(200),
        action_url VARCHAR(200),
        source VARCHAR(30),    PRIMARY KEY(id)
    )ENGINE=INNODB DEFAULT CHARSET=utf8;

    Scrapy與scrapy-splash框架快速載入js頁面

    #
    class NewsPipeline(object):
        def __init__(self):
            self.conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='root', db='db_news',charset='utf8')
            self.cursor = self.conn.cursor()    def process_item(self, item, spider):
            sql = '''insert into tb_google_news (title,Scrapy與scrapy-splash框架快速載入js頁面_url,action_url,source) values(%s,%s,%s,%s)'''
            self.cursor.execute(sql, (item["title"], item["Scrapy與scrapy-splash框架快速載入js頁面_url"], item["action_url"], item["source"]))
            self.conn.commit()        return item    def close_spider(self):
            self.cursor.close()
            self.conn.close()

    NewsPipeline類別

    scrapy crawl google_news
    3.5 執行scrapy爬蟲

    ###在控制台執行:###rrreee###資料庫中展示如下圖:############## ##相關推薦:#########有關scrapy指令的基本介紹#############安裝Scrapy教學###########scrapy爬蟲框架的介紹######

    以上是Scrapy與scrapy-splash框架快速載入js頁面的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn