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网络爬虫》

你可能感兴趣的:(爬虫,python)