介绍
在日常爬取过程中,动态网站的爬取是比较麻烦的,因为动态网站的数据是动态加载的,这时候我们需要用上selenuim中间件去模拟操作,获取动态数据
开始
创建项目
1.scrapy startproject Taobao
2.cd Taobao
3. scrapy genspider taobao www.taobao.com
打开项目
首先我们什么不做来爬取看看,先把setting里面的爬虫规则设置为False
ROBOTSTXT_OBEY = False
我们在终端输入
scrapy view "http://www.taobao.com"
这时候会发现爬取到的页面如下所示:
使用中间件
我们关注下载中间件( TaobaoDownloaderMiddleware)里面的process_request函数 我们添上一行代码看看什么效果:
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
# Must either:
# - return None: continue processing this request
# - or return a Response object
# - or return a Request object
# - or raise IgnoreRequest: process_exception() methods of
# installed downloader middleware will be called
print("------我是中间件,请求经过我------")
return None
然后在seeting里面,把下面的注释去掉
DOWNLOADER_MIDDLEWARES = {
'Taobao.middlewares.TaobaoDownloaderMiddleware': 543,
}
我们运行一下看看效果:
scrapy view "http://www.taobao.com"
效果:
------我是中间件,请求经过我------
2018-08-29 15:38:21 [scrapy.downloadermiddlewares.redirect] DEBUG: Redirecting (302) to <GET https://www.taobao.com/> from <GET http://www.taobao.com>
------我是中间件,请求经过我------
2018-08-29 15:38:21 [scrapy.core.engine] DEBUG: Crawled (200) <GET https://www.taobao.com/> (referer: None)
说明中间件是有效果的,如果我们在中间件模拟一些操作,是不是就能获取动态数据呢?
middlewares中间件的操作
首先导入selenium
from selenium import webdriver
#无界面运行
from selenium.webdriver.chrome.options import Options
在 process_request函数中写入如下代码
def process_request(self, request, spider):
# Called for each request that goes through the downloader
# middleware.
print("------我是中间件,请求经过我------")
#设置无界面运行
option = Options()
option.add_argument("--headless")
#创建一个driver对象
#driver = webdriver.Chrome()
driver = webdriver.Chrome(chrome_options=option)
#等待15秒
driver.implicitly_wait(15)
driver.get(request.url)
# 让页面滚动最底层 模拟人的操作
js = 'window.scrollTo(0,document.body.scrollHeight)'
# 执行js
driver.execute_script(js)
# 获取内容
content = driver.page_source
from scrapy.http import HtmlResponse
# 创建一个resp对象返回至解析函数
resp = HtmlResponse(request.url,request=request,body=content,encoding='utf-8')
return resp
return None
好了,这时已经获取到动态数据了,这里就不解析了,以上就是动态网站爬取的思路