Scrapy和Selenium结合使用完整步骤

Scrapy和Selenium结合使用完整步骤

一、环境安装

1. 安装Scrapy

在命令行执行以下指令:

pip install scrapy

2. 安装Selenium

pip install selenium

3. 安装scrapy_selenium

pip install scrapy_selenium

4. 安装 chrome-headless-shell 和 chromedriver

打开chrome浏览器 Google Chrome Testing 选择适合的版本

apt install -y libx11-dev libx264-dev libnss3 libgconf-2-4 libatk-bridge2.0-0 libatspi2.0-0 libcups2 libxcomposite1 libxrandr2 libayatana-appindicator3-1 libgbm1 libasound2  && \
cd /soft && \
wget https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.204/linux64/chromedriver-linux64.zip && \
unzip -j chromedriver-linux64.zip -d chromedriver && \
cp chromedriver/chromedriver /usr/local/bin/chromedriver && \
wget https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.204/linux64/chrome-headless-shell-linux64.zip && \
unzip -j chrome-headless-shell-linux64.zip -d chrome_headless_shell && \
ln -s /soft/chrome_headless_shell/chrome-headless-shell /usr/local/bin/chrome

查看chromedriver是否可运行

chromedriver --version#出现版本号正常展示即代表安装成功
#ChromeDriver 131.0.6778.204 (52183f9**************53d256f1516f2a0-refs/branch-heads/6***_1*5@{#7})

二、Scrapy优化配置

1. 创建Scrapy项目

scrapy startproject product_collection

2. 创建普通模板爬虫

进入spiders目录,生成爬虫文件:

cd product_collection/product_collection/spiders
scrapy genspider items <url>

运行爬虫:

scrapy crawl items

3. 创建自动爬取多页数据的crawl模板

cd product_collection/product_collection/spiders
scrapy genspider -t crawl items <url>
scrapy crawl items

三、处理scrapy_selenium与Selenium版本不兼容问题

在scrapy_selenium最新版本0.0.7中,它与Selenium版本4.x不兼容。使用默认配置时,将报出下列错误:

TypeError: WebDriver.__init__() got an unexpected keyword argument 'executable_path'

解决方案(二选一)

1. 降低已安装的Selenium版本

使用Selenium 3.x和与之兼容的urllib3版本:

pip uninstall selenium
pip install 'selenium<4'	#默认会安装selenium3.141.0版本pip uninstall urllib3
pip install urllib3==1.26.2

注:urllib3高版本不兼容Selenium 3.x,所以需与之修改。

2. 修改scrapy_selenium插件源码

从GitHub上克隆scrapy_selenium的代码,重新修改并安装自己的版本:

源码地址:

https://github.com/clemfromspace/scrapy-selenium

Fork到自己仓库并clone到本地:
  • 首先fork代码到自己的github仓库
    https://github.com/clemfromspace/scrapy-selenium/fork

  • clone源码到本地并进行修改

git clone https://github.com/<your_username>/scrapy-selenium
修改middlewares.py

scrapy_selenium/middlewares.py中将有关代码修改为:

"""This module contains the ``SeleniumMiddleware`` scrapy middleware"""from scrapy import signals
from scrapy.exceptions import NotConfigured
from scrapy.http import HtmlResponse
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWaitfrom .http import SeleniumRequestclass SeleniumMiddleware:"""Scrapy middleware handling the requests using selenium"""def __init__(self, driver_name, command_executor, driver_arguments):# def __init__(self, driver_name, driver_executable_path,#     browser_executable_path, command_executor, driver_arguments):"""Initialize the selenium webdriverParameters----------driver_name: strThe selenium ``WebDriver`` to usedriver_executable_path: strThe path of the executable binary of the driverdriver_arguments: listA list of arguments to initialize the driverbrowser_executable_path: strThe path of the executable binary of the browsercommand_executor: strSelenium remote server endpoint"""driver_name = driver_name.lower().capitalize()driver_options = getattr(webdriver, f"{driver_name}Options")()for argument in driver_arguments:driver_options.add_argument(argument)if command_executor:self.driver = webdriver.Remote(command_executor=command_executor,options=driver_options)else:driver_class = getattr(webdriver, driver_name)self.driver = driver_class(options=driver_options)# webdriver_base_path = f'selenium.webdriver.{driver_name}'# driver_klass_module = import_module(f'{webdriver_base_path}.webdriver')# driver_klass = getattr(driver_klass_module, 'WebDriver')# driver_options_module = import_module(f'{webdriver_base_path}.options')# driver_options_klass = getattr(driver_options_module, 'Options')# driver_options = driver_options_klass()# if browser_executable_path:#     driver_options.binary_location = browser_executable_path# for argument in driver_arguments:#     driver_options.add_argument(argument)# driver_kwargs = {#     'executable_path': driver_executable_path,#     f'{driver_name}_options': driver_options# }# # locally installed driver# if driver_executable_path is not None:#     driver_kwargs = {#         'executable_path': driver_executable_path,#         f'{driver_name}_options': driver_options#     }#     self.driver = driver_klass(**driver_kwargs)# # remote driver# elif command_executor is not None:#     from selenium import webdriver#     capabilities = driver_options.to_capabilities()#     self.driver = webdriver.Remote(command_executor=command_executor,#                                    desired_capabilities=capabilities)@classmethoddef from_crawler(cls, crawler):"""Initialize the middleware with the crawler settings"""driver_name = crawler.settings.get('SELENIUM_DRIVER_NAME')# driver_executable_path = crawler.settings.get('SELENIUM_DRIVER_EXECUTABLE_PATH')# browser_executable_path = crawler.settings.get('SELENIUM_BROWSER_EXECUTABLE_PATH')command_executor = crawler.settings.get('SELENIUM_COMMAND_EXECUTOR')driver_arguments = crawler.settings.get('SELENIUM_DRIVER_ARGUMENTS')if driver_name is None:raise NotConfigured('SELENIUM_DRIVER_NAME must be set')# if driver_executable_path is None and command_executor is None:#     raise NotConfigured('Either SELENIUM_DRIVER_EXECUTABLE_PATH '#                         'or SELENIUM_COMMAND_EXECUTOR must be set')middleware = cls(driver_name=driver_name,# driver_executable_path=driver_executable_path,# browser_executable_path=browser_executable_path,command_executor=command_executor,driver_arguments=driver_arguments)crawler.signals.connect(middleware.spider_closed, signals.spider_closed)return middlewaredef process_request(self, request, spider):"""Process a request using the selenium driver if applicable"""if not isinstance(request, SeleniumRequest):return Noneself.driver.get(request.url)for cookie_name, cookie_value in request.cookies.items():self.driver.add_cookie({'name': cookie_name,'value': cookie_value})if request.wait_until:WebDriverWait(self.driver, request.wait_time).until(request.wait_until)if request.screenshot:request.meta['screenshot'] = self.driver.get_screenshot_as_png()if request.script:self.driver.execute_script(request.script)body = str.encode(self.driver.page_source)# Expose the driver via the "meta" attributerequest.meta.update({'driver': self.driver})return HtmlResponse(self.driver.current_url,body=body,encoding='utf-8',request=request)def spider_closed(self):"""Shutdown the driver when spider is closed"""self.driver.quit()
修改setup.cfg
"""This module contains the packaging routine for the pybook package"""from setuptools import setup, find_packages
try:from pip._internal.network.session import PipSessionfrom pip._internal.req import parse_requirements
except ImportError:# It is quick hack to support pip 10 that has changed its internal# structure of the modules.from pip._internal.network.session import PipSessionfrom pip._internal.req.req_file import parse_requirementsdef get_requirements(source):"""Get the requirements from the given ``source``Parameters----------source: strThe filename containing the requirements"""install_reqs = parse_requirements(filename=source, session=PipSession())return [str(ir.requirement) for ir in install_reqs]setup(packages=find_packages(),install_requires=get_requirements('requirements/requirements.txt')
)
修改完成后,重新打包安装:
pip uninstall scrapy-selenium
pip install git+https://github.com/<your_username>/scrapy-selenium

四、Scrapy和Selenium配置

在Scrapy项目的settings.py中添加下列配置:

# Selenium相关配置
# 使用 Chrome 浏览器
SELENIUM_DRIVER_NAME = 'chrome'
# Chrome浏览器 路径 
SELENIUM_BROWSER_EXECUTABLE_PATH = '/path/to/chrome'
# 配置为无头浏览器模式
SELENIUM_DRIVER_ARGUMENTS = ['--headless','--no-sandbox','--disable-dev-shm-usage','--disable-gpu',#'--start-maximized','--window-size=1920x1080'
]

五、使用自定义Middleware实现Selenium支持

如果不想使用scrapy_selenium插件,可以自己编写一个Middleware来实现Selenium支持。

1. 创建SeleniumMiddleware

在项目目录下的middlewares.py文件中,添加以下代码:

from scrapy.http import HtmlResponse
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import Byclass SeleniumMiddleware:def __init__(self):chrome_options = Options()chrome_options.add_argument("--headless")  # 启用无头模式chrome_options.add_argument("--disable-gpu")chrome_options.add_argument("--no-sandbox")chrome_options.add_argument("--disable-dev-shm-usage")chrome_options.add_argument("--start-maximized")# 明确指定 Chrome 二进制文件路径chrome_options.binary_location = ("/path/to/chrome-headless-shell")self.driver = webdriver.Chrome(service=Service('/path/to/chromedriver'), options=chrome_options)@classmethoddef from_crawler(cls, crawler):s = cls()crawler.signals.connect(s.spider_closed, signal=signals.spider_closed)return sdef process_request(self, request, spider):if 'selenium' in request.meta:#使用selenium打开请求的urlself.driver.get(request.url)# 显示等待页面指定元素出现WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.XPATH, '<XPATH语法>')))# 将滚动条拖到最底端self.toBottom(self.driver)body=self.driver.page_sourceresponseUrl = self.driver.current_url# 关闭打开的页面self.driver.close()return HtmlResponse(url=responseUrl,body=body,encoding='utf-8',request=request)def spider_closed(self, spider):#注销chrome实例self.driver.quit()def toBottom(self,driver):driver.execute_script("document.documentElement.scrollTop = 100000")

2. 激活Middleware

settings.py中启用自定义的Middleware:

DOWNLOADER_MIDDLEWARES = {'product_collection.middlewares.SeleniumMiddleware': 543,
}

3. 在爬虫中使用

在爬虫的请求中设置meta属性:

yield scrapy.Request(url=<url>, meta={'selenium': True})

六、注意点

  1. 确保Scrapy、Selenium和指定源码版本兼容。
  2. Selenium需要应用最新的driver支持,如有问题,可使用webdriver-manager 自动管理driver。
  3. 如要比较优化效率,可考虑在静态部分使用Scrapy,在动态内容使用Selenium。

通过上述步骤,您可以成功将Scrapy和Selenium结合使用,充分发挥两者的优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ReactiveStreams、Reactor、SpringWebFlux

注意&#xff1a; 本文内容于 2024-12-28 21:22:12 创建&#xff0c;可能不会在此平台上进行更新。如果您希望查看最新版本或更多相关内容&#xff0c;请访问原文地址&#xff1a;ReactiveStreams、Reactor、SpringWebFlux。感谢您的关注与支持&#xff01; ReactiveStreams是…

Android笔试面试题AI答之Android基础(8)

Android入门请看《Android应用开发项目式教程》&#xff0c;视频、源码、答疑&#xff0c;手把手教 文章目录 1.Android新建工程需要注意的地方有哪些&#xff1f;**1. 选择合适的项目模板****2. 配置项目基本信息****3. 选择最低 SDK 版本****4. 配置构建工具****5. 选择编程…

【阻塞队列】- ArrayBlockingQueue 的原理-迭代器

文章目录 1. 前言2. 迭代器3. Itrs3.1 参数3.2 迭代器 Itr3.2.1 参数3.2.2 构造器3.2.3 hasNext3.2.4 next3.2.5 remove3.2.6 shutdown3.2.7 removedAt3.2.8 takeIndexWrapped 3.3 doSomeSweeping&#xff08;tryHandler&#xff09;3.4 register3.5 takeIndexWrapped3.6 remov…

ARM 汇编基础总结

GNU 汇编语法 编写汇编的过程中&#xff0c;其指令、寄存器名等可以全部使用大写&#xff0c;也可以全部使用小写&#xff0c;但是不能大小写混用。 1. 汇编语句的格式 label: instruction comment label即标号&#xff0c;表示地址位置&#xff0c;有些指令前面可能会有标…

【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库

**前言&#xff1a;**本节内容介绍使用C/C访问数据库&#xff0c; 包括对数据库的增删查改操作。 主要是学习一些接口的调用&#xff0c; 废话不多说&#xff0c; 开始我们的学习吧&#xff01; ps:本节内容比较容易&#xff0c; 友友们放心观看哦&#xff01; 目录 准备mysql…

华为配置 之 RIP

简介&#xff1a; RIP&#xff08;路由信息协议&#xff09;是一种广泛使用的内部网关协议&#xff0c;基于距离向量算法来决定路径。它通过向全网广播路由控制信息来动态交换网络拓扑信息&#xff0c;从而计算出最佳路由路径。RIP易于配置和理解&#xff0c;非常适用于小型网络…

1.GPU简介及英伟达开发环境配置

前言 This book shows how, by harnessing the power of your computer’s graphics process unit (GPU), you can write high-performance software for a wide rangeof applications.Although originally designed to render computer graphics ona monitor (and still used…

电脑cxcore100.dll丢失怎么办?

电脑运行时常见问题解析&#xff1a;应对DLL文件丢失、文件损坏与系统报错的实用指南 在数字时代&#xff0c;电脑已成为我们工作、学习和娱乐不可或缺的工具。然而&#xff0c;正如任何精密机械都可能遇到故障&#xff0c;电脑在运行过程中也难免会遇到各种问题&#xff0c;如…

【无线传感网】时间同步技术

文章目录 时间同步模型时钟模型1. 节点本地时钟模型2. 节点逻辑时钟模型 通信模型1. 单向报文传递2. 双向报文交换3. 广播参考报文4. 参数拟合技术 时钟同步的误差来源 时间同步协议时钟同步的类别1. 时钟速率同步与偏移同步2. 同步期限&#xff1a;长期同步与按需同步3. 同步范…

C# 实用工具分享(1)

大家好&#xff0c;今天分享一些在开发过程中比较实用的工具。 首先在软件开发的过程中不可避免的要使用截图这样的功能&#xff0c;以前这样的功能我自己也是选择开发出新功能。但是自己开发还是非常费时费力的&#xff0c;并且效果也不一定特别好。 于是我找到了一个现成的…

积分图(Integral Image)与均值滤波的快速实现

积分图&#xff08;Integral Image&#xff09;也称为求和图&#xff08;Summed Area Table&#xff09;&#xff0c;是一种用于快速计算图像中任意矩形区域像素值总和的技术。 基本概念 积分图的每个位置(i, j)存储的是从图像左上角(1, 1)到当前位置(i, j)所有像素值的累积和…

curl+openssl 踩坑笔记

curl编译&#xff1a;点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …

[AI] 深度学习的“黑箱”探索:从解释性到透明性

目录 1. 深度学习的“黑箱”问题&#xff1a;何为不可解释&#xff1f; 1.1 为什么“黑箱”问题存在&#xff1f; 2. 可解释性研究的现状 2.1 模型解释的方法 2.1.1 后置可解释性方法&#xff08;Post-hoc Explanations&#xff09; 2.1.2 内在可解释性方法&#xff08;I…

python-Flask:SQLite数据库路径不正确但是成功访问到了数据库,并对表进行了操作

出现了这个问题&#xff0c;就好像是我要去找在南方的人&#xff0c;然后我刚好不分南北&#xff0c;我认为的方向错了&#xff0c;实则方向对了。 在我针对复盘解决&#xff1a;sqlite3.OperationalError: unrecognized token: “{“-CSDN博客这个内容的时候&#xff0c;又出现…

对称密码算法(分组密码算法 序列密码算法 密码杂凑算法)中的基本操作

对称密码算法(分组密码算法 序列密码算法 密码杂凑算法)中的基本操作 相比非对称加密算法&#xff0c;对称加密算法因为加解密效率较高&#xff0c;因而在日常使用中更加广泛。为了让大家更加熟悉常见的对称加密算法&#xff0c;本文列举出了对称密码算法设计中经常用到的13种基…

大数据治理,数字化转型运营平台建设方案(PPT完整版)

1、大数据治理整体运营思路 2、数据资产定义及流程规范 3、治理规范及质量管控 4、质量考核标准及提升方案 软件全套资料部分文档清单&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划…

专题十四——BFS

目录 一BFS解决FloodFill算法 1图像渲染 2岛屿数量 3岛屿的最大面积 4被环绕的区域 二BFS解决蛋源最短路径问题 1迷宫中离入口最近的出口 2最小基因变化 3单词接龙 4为高尔夫比赛砍树 三BFS解决多源最短路径问题 1 01矩阵 2飞地的数量 3地图中的最高点 4地图分…

DMDRS部署:搭建DM8-DM8数据同步

一、部署要求 1.1 硬件要求 DMDRS服务描述源DMDRS 内存要求至少2GB的内存空间。推荐配置4GB及以上的内存空间。 源DMDRS对内存空间的需求主要与装载的并发数相关。当内存空间配置低于2GB时&#xff0c;可以调整装载的线程数来降低源DMDRS对内存空间的需求。 磁盘要求至少10GB…

仓颉笔记——windows11安装启用cangjie语言,并使用vscode编写“你好,世界”

2025年1月1日第一篇日记&#xff0c;大家新年好。 去年就大致看了一下&#xff0c;感觉还不错&#xff0c;但一直没上手&#xff0c;这次借着元旦的晚上安装了一下&#xff0c;今年正式开动&#xff0c;公司众多的应用国产化正等着~~ 第一步&#xff1a;准备 官网&#xff1a;…

datalist的作用?怎么用的?

在 HTML 中&#xff0c;<datalist> 元素用于为 <input> 元素提供一个可选项列表&#xff0c;帮助用户通过预定义的选项进行快速选择。它是一个增强输入体验的功能&#xff0c;类似于自动完成&#xff08;autocomplete&#xff09;&#xff0c;但与传统的 <selec…