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.rhkb.cn/news/500553.html

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

相关文章

Flink源码解析之:如何根据JobGraph生成ExecutionGraph

Flink源码解析之&#xff1a;如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中&#xff0c;我们介绍了Flink如何根据StreamGraph生成JobGraph的流程&#xff0c;并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…

LeetCode算法题——有序数组的平方

题目描述 给你一个按非递减顺序排序的整数数组nums&#xff0c;返回每个数字的平方组成的新数组&#xff0c;要求也按非递减顺序排序。 题解 解法一&#xff1a;暴力解法 思路&#xff1a; 该题目可通过暴力解法解决&#xff0c;即利用for循环遍历数组&#xff0c;对数组每…

【Python】FastAPI之SQLAlchemy、关联关系

第四节&#xff1a;SQLAlchemy操作数据库 一、SQLAlchemy介绍 SQLAlchemy 是一个功能强大且灵活的 Python SQL 工具包及对象关系映射&#xff08;ORM&#xff09;库&#xff0c;它提供了全面的数据库访问抽象层。通过 SQLAlchemy&#xff0c;开发者可以使用 Python 代码来定义…

GRAPE——RLAIF微调VLA模型:通过偏好对齐提升机器人策略的泛化能力(含24年具身模型汇总)

前言 过去的这两年&#xff0c;工作之余&#xff0c;我狂写大模型与具身的文章&#xff0c;加之具身大火&#xff0c;每周都有各种朋友通过CSDN私我及我司「七月在线」寻求帮助/指导(当然&#xff0c;也欢迎各大开发团队与我司合作共同交付&#xff09;&#xff1a; 要么是做…

基于 LangChain 实现数据库问答机器人

基于 LangChain 实现数据库问答机器人 一、简介二、应用场景三、实战案例1、需求说明2、实现思路3、对应源码 一、简介 在 Retrieval 或者 ReACT 的一些场景中&#xff0c;常常需要数据库与人工智能结合。而 LangChain 本身就封装了许多相关的内容&#xff0c;在其官方文档-SQ…

Kali 自动化换源脚本编写与使用

1. 背景与需求 在使用 Kali Linux 的过程中&#xff0c;软件源的配置对系统的更新与软件安装速度至关重要。 Kali 的默认官方源提供了安全且最新的软件包&#xff0c;但有时由于网络条件或地理位置的限制&#xff0c;使用官方源可能会出现速度较慢的问题。 为了解决这一问题&a…

1Panel自建RustDesk服务器方案实现Windows远程macOS

文章目录 缘起RustDesk 基本信息实现原理中继服务器的配置建议 中继服务器自建指南准备服务器安装1Panel安装和配置 RustDesk 中继服务防火墙配置和安全组配置查看key下载&安装&配置客户端设置永久密码测试连接 macOS安装客户端提示finder写入失败hbbs和hbbr说明**hbbs…

Maple软件的安装和使用

文章目录 1.前言说明2.我为什么要学习Maple3.软件的安装4.如何使用4.1基本的赋值语句4.2函数的定义4.3三个类型的书写介质 5.指数运算5.1使用面板5.2自己输入 6.对数的使用 1.前言说明 众所周知&#xff0c;我虽然是一名这个计算机专业的学生&#xff0c;但是我对于数学&#…

Nacos配置中心总结

Nacos配置中心总结 Nacos配置文件的加载顺序和优先级 加载顺序 nacos作为配置中心时&#xff0c;需要在bootstrap.yml文件中添加nacos config相关的配置&#xff0c;这样系统启动时就能先去拉取nacos server上的配置了。拉取过来后会和本地配置文件进行合并。 bootstrap.ym…

Java开发-后端请求成功,前端显示失败

文章目录 报错解决方案1. 后端未配置跨域支持2. 后端响应的 Content-Type 或 CORS 配置问题3. 前端 request 配置问题4. 浏览器缓存或代理问题5. 后端端口未被正确映射 报错 如下图&#xff0c;后端显示请求成功&#xff0c;前端显示失败 解决方案 1. 后端未配置跨域支持 …

springboot523基于Spring Boot的大学校园生活信息平台的设计与实现(论文+源码)_kaic

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本大学校园生活信息平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据…

【Ubuntu使用技巧】Ubuntu22.04无人值守Crontab工具实战详解

一个愿意伫立在巨人肩膀上的农民...... Crontab是Linux和类Unix操作系统下的一个任务调度工具&#xff0c;用于周期性地执行指定的任务或命令。Crontab允许用户创建和管理计划任务&#xff0c;以便在特定的时间间隔或时间点自动运行命令或脚本。这些任务可以按照分钟、小时、日…

Linux(14)——网络管理

目录 一、检测网络配置&#xff1a; 1、查看网络接口&#xff08;ip&#xff09;&#xff1a; 2、查看性能&#xff08;ip&#xff09;&#xff1a; 3、查看 IP 地址&#xff08;ip&#xff09;&#xff1a; 4、查看路由表&#xff08;ip&#xff09;&#xff1a; 5、追踪…

《机器学习》——线性回归模型

文章目录 线性回归模型简介一元线性回归模型多元线性回归模型误差项分析一元线性模型实例完整代码 多元线性模型实例完整代码 线性回归模型简介 线性回归是利用数理统计中回归分析&#xff0c;来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。 相关关系&…

GeoTrust True BusinessID Wildcard

GeoTrust由DigiCert 提供支持&#xff0c;是最受信任和尊重的品牌之一&#xff0c;以提供高保证的网站安全而闻名。 GeoTrust True BusinessID通配符证书 – 以低成本保护多个主机名。即使将其用于您的公司主页或电子邮件服务器主机名&#xff0c;保护所有敏感信息也是您的目标…

华为配置 之 链路聚合

简介&#xff1a; 链路聚合&#xff08;Link Aggregation&#xff09;是一种计算机网络技术&#xff0c;通过将多个物理端口汇聚在一起&#xff0c;形成一个逻辑端口&#xff0c;以实现出/入流量吞吐量在各成员端口的负荷分担。当交换机检测到其中一个成员端口的链路发生故障时…

Angular Firebase CRUD 项目推荐

Angular Firebase CRUD 项目推荐 angular-firebase-crud Angular CRUD with Firebase using cloud firestore as a database, angular material and Bootstrap 4. Step by Step tutorial and working angular 7 example app. 项目地址: https://gitcode.com/gh_mirrors/an/an…

SqlSession的线程安全问题源码分析

&#x1f3ae; 作者主页&#xff1a;点击 &#x1f381; 完整专栏和代码&#xff1a;点击 &#x1f3e1; 博客主页&#xff1a;点击 文章目录 SqlSession 是线程安全的吗&#xff1f;为什么说是线程不安全的&#xff1f;事务管理问题 数据库连接的共享问题 一级缓存线程安全问题…

gitlab的搭建及使用

1、环境准备 服务器准备 CentOS Linux release 7.9.2009 (Core)&#xff0c;内存至少4G。 修改主机名和配置ip地址 hostnamectl set-hostname <hostname> 关闭主机的防火墙 # 关闭防火墙 systemctl stop firewalld #临时关闭防火墙 systemctl disable firewalld …

【面试系列】深入浅出 Spring Boot

熟悉SpringBoot&#xff0c;对常用注解、自动装配原理、Jar启动流程、自定义Starter有一定的理解&#xff1b; 面试题 Spring Boot 的核心注解是哪个&#xff1f;它主要由哪几个注解组成的&#xff1f;Spring Boot的自动配置原理是什么&#xff1f;你如何理解 Spring Boot 配置…