Selenium在Scrapy中处理动态加载数据的完整指南
本文详解如何在Scrapy框架中集成Selenium以解决动态加载数据的爬取难题。通过配置Spider与下载中间件,利用浏览器对象执行页面滚动并获取渲染后的HTML源码,成功抓取网易新闻多个版块的动态内容。文章提供了完整的代码实现、配置步骤及注意事项,帮助开发者高效处理复杂动态网页。
在使用Scrapy框架进行网站数据爬取时,经常遇到页面数据通过JavaScript动态加载的情况。若直接通过Scrapy发送请求,无法获取这些动态生成的数据。然而,通过浏览器访问同一URL时,数据却能正常加载。为了在Scrapy中获取此类动态数据,必须引入Selenium创建浏览器实例,并通过该实例发送请求以获取完整的动态内容。本文将详细介绍Selenium在Scrapy中的具体应用方法。
使用目的
本案例旨在爬取网易新闻的国内、国际、军事及航空四个版块的新闻内容。测试发现,这些版块的数据均为动态加载,直接爬取无法获取有效信息,因此采用Selenium辅助获取这部分数据。
代码
Spider实现
import scrapy
from selenium import webdriver
from wangyiPro.items import WangyiproItem
class WangyiSpider(scrapy.Spider):
name = 'wangyi'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://news.163.com/']
model_url = []
hro = webdriver.Chrome()
def parse(self, response):
# 从所有版块中筛选出所需要下载的4个版块
li_list = response.xpath('/html/body/div[1]/div[1]/div[2]/div[2]/div[2]/div[2]/div/ul/li')
indexs = [3,4,6,7]
for index in indexs:
model_li = li_list[index]
model_list = model_li.xpath('./a/@href').extract_first()
self.model_url.append(model_list)
for url in self.model_url:
yield scrapy.Request(url=url,callback=self.parse_model)
# 数据解析:新闻标题+新闻详情页的url(动态加载数据)
def parse_model(self,response):
# 直接对response解析无法获取该数据(动态加载数据)
# 无法拿到动态加载数据返回的响应数据就不足
# 使用中间件修改不满足需求的响应对象中的响应数据,将其改为包含动态加载数据的响应数据
div_list = response.xpath('/html/body/div/div[3]/div[4]/div[1]/div[1]/div/ul/li/div/div')
for div in div_list:
title = div.xpath('./div/div[1]/h3/a/text()').extract_first()
new_url_detail = div.xpath('./div/div[1]/h3/a/@href').extract_first()
if new_url_detail:
item = WangyiproItem()
item['title'] = title
yield scrapy.Request(url=new_url_detail,callback=self.parse_detail,meta={'item':item})
def parse_detail(self,response):
# 返回的列表,需要将其转换为字符串
content = response.xpath('/html/body/div[3]/div[1]/div[3]/div[2]/p/text()').extract()
content = ''.join(content)
item = response.meta['item']
item['content'] = content
yield item
# 重写爬虫类父类方法,该方法在爬虫程序执行结束后立即执行
def closed(self,spider):
# 打开selenium需要关闭
self.hro.quit()
中间件配置
from time import sleep
from scrapy.http import HtmlResponse#scrapy封装好的响应类
class WangyiproDownloaderMiddleware:
def process_request(self, request, spider):
return None
# 拦截所有的响应对象
# 整个工程发起的请求:1+4+n 对应相同的响应
def process_response(self, request, response, spider):
# 从所有拦截对象中找到4个需修改的响应对象
if request.url in spider.model_url:
hro = spider.hro
hro.get(request.url)
sleep(2)
# 网页下拉到底,获取更多动态加载数据
hro.execute_script('window.scrollTo(0,document.body.scrollHeight)')
sleep(1)
page_text = hro.page_source
# response.text = page_text
# 返回一个新的响应对象
return HtmlResponse(url=request.url,body=page_text,encoding='utf-8',request=request)
# 如果不是需要修改的响应数据,不做修改
else:
return response
def process_exception(self, request, exception, spider):
pass
运行效果

总结
hro = webdriver.Chrome()我是直接将Chromedriver写入配置文件,所以直接实例化对象即可,如果没有写入配置文件,写为hro = webdriver.Chrome(executable_path='绝对路径')。尝试过将Chromedriver放到pycharm的文件下写入相对路径,没有成功。- 使用selenium在结束后需要关闭,可以改写爬虫类父类方法closed()
- settings里修改三件套并且打开下载中间件和items
以上就是selenium如何在scrapy中的使用的详细内容,更多关于scrapy中使用selenium的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













