天天看點

python爬蟲selenium和splash_Python scrapy 爬蟲入門(五)動态渲染頁面的爬取(selenium 和 splash)...

1 Selenium實作動态頁面爬取

1.1 安裝python 支援的Selenium庫

pip install selenium

1.2 安裝浏覽器驅動程式

chromedriver 的下載下傳位址:https://chromedriver.storage.googleapis.com/index.html 或者 http://npm.taobao.org/mirrors/chromedriver/。 下載下傳符合自己的版本即可。

下載下傳及解壓後将 chromedriver.exe 檔案放在python 目錄下(例如:C:\Program Files\Python37)

1.3 項目執行個體

實作項目時與普通的爬蟲項目基本一樣,隻不過爬取頁面時使用 selenuum 的文法,并且需要實作下載下傳器中間件(例如:xxxDownloaderMiddleware), 實作後在settings.py 檔案中啟用該檔案即可。

2 Splash實作動态頁面爬取

Selenium極大地友善了動态頁面的資料提取,但是它需要操作浏覽器,無法實作異步和大規模頁面的爬取需求。使用Splash就可以解決上述問題。

在使用Splash前,需要安裝以下3個工具或子產品。

Splash:一個JavaScript的渲染服務,帶有HTTP API的輕量級Web浏覽器。

Docker:一種容器引擎,Splash需要在Docker中安裝和運作。

Scrapy-Splash:實作Scrapy中使用Splash的子產品。

2.1 下載下傳和安裝 docker

以Windows下安裝Docker為例。不同的Windows版本,Docker的安裝包不一樣,主要分為兩種:(1)Windows 10專業版及企業版64位:下載下傳Docker for Windows。官方下載下傳位址為https://store.docker.com/editions/community/docker-ce-desktop-windows。

(2)其他Windows版本:下載下傳Docker toolbox。這是一個Docker工具集。官方下載下傳位址為https://docs.docker.com/toolbox/overview/#ready-to-get-started。國内可以使用阿裡雲的鏡像來下載下傳,下載下傳位址為http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/。

關于Linux和Mac OS下的Docker安裝及使用,官方網站都有詳細的教程,位址為https://docs.docker.com/,讀者也可以參考菜鳥網絡,位址為http://www.runoob.com/docker/windows-docker-install.html

2.2 拉取和開啟Splash

docker 啟動後,執行指令拉取splash 鏡像:

docker pull scrapinghub/splash

開啟 splash 指令為:

docker run -p 8050:8050 scrapinghub/splash

2.3 Scrapy-Splash的安裝

pip install scrapy-splash

但由于 splash 需要運作在 docker 上,由于記憶體不足,本機docker 不能運作,先記錄備份,之後會回來補充。

2.4 splash 官方說明文檔

文檔連結為:https://splash.readthedocs.io/en/latest/index.html

2.5 項目執行個體

2.5.1 建立項目

建立一個名為 yihaodian 的 scrapy 項目

scrapy startproject yihaodian

2.5.2 配置scrapy-splash環境

在項目配置檔案settings.py中,需要配置scrapy-splash,配置内容如下:

ROBOTSTXT_OBEY = False

#設定Splash伺服器位址(ip和port 為docker 中的ip和port )

SPLASH_URL = 'http://ip:port'

# 設定去重過濾器

DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'

# 設定緩存

HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

# 支援 cache_ars(可選)

SPIDER_MIDDLEWARES = {

'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,

}

# 開啟Splash的兩個下載下傳器中間件并調整HttpCompressionMiddleware的次序

DOWNLOAD_MIDDLEWARES = {

#将splash middleware 添加到DOWNLOAD_MIDDLEWARE中

'scrapy_splash.SplashCookieMiddleware': 723,

'scrapy_splash.SplashMiddleware': 725,

'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,

}

2.5.3 item 封裝資料

打開項目yihaodian中的items.py源檔案,添加商品資訊字段,實作代碼如下:

import scrapy

class YihaodianItem(scrapy.Item):

price = scrapy.Field()

title = scrapy.Field()

positiveRatio = scrapy.Field()

storeName = scrapy.Field()

2.5.4 建立Spider檔案及Spider類

在Spiders檔案夾中建立iphone_spider.py檔案,在iphone_spider.py中建立爬蟲類PhoneSpider,實作代碼如下:

from scrapy import Request

from scrapy.spiders import Spider

from yihaodian.items import YihaodianItem

from scrapy_splash import SlashRequest

lua_script = """

function main(splash, args)

splash:go(args.url)

splash:wait(args.wait)

splash:runjs("document.getElementByClassName('mod_trun_page clearfix mt20')[0].scrollIntoView(true)")

splash:wait(args.wait)

return splash:html()

end

"""

class PhoneSpider(Spider):

name = 'iphone'

url = 'http://search.yhd.com/c0-0/kiphone'

def start_requests(self):

yield SplashRequest(self.url, callback=self.parse, endpoint='execute', args={'lua_source':lua_script, 'images':0, 'wait':3}, cahce_args=['lua_source'])

def parse(self, response):

item = YihaodianItem()

list_selector = response.xpath("//div[@class='itemBox']")

for one_selector in list_selector:

try:

price = one_selector.xpath(".//em[@class='num']/text()").extract()[-1]

price = price.strip("\n\t")

title = one_selector.xpath("p[@class='proName clearfix']/a/text()").extract()[-1]

title = price.strip("\n\t")

positiveRatio = one_selector.xpath(".//span[@class='positiveRatio']/text()").extract()[0]

storeName = one_selector.xpath(".//span[@class]='shop_text']/text()").extract()[0]

item["price"] = price

item["title"] = title

item["positiveRatio"] = positiveRatio

item["storeName"] = storeName

yield item

except:

continue

next_url = response.xpath("//a[@class='page_next']/@href).extract_first()

if next_url:

next_url = response.urljoin(next_url)

yield SplashRequest(next_url, callback=self.parse, endpoint='execute', args={'lua_source':lua_script, 'images':0, 'wait': 3})

之後運作項目即可。

文章内容參考《從零開始學Scrapy網絡爬蟲》