Scrapy和Selenium整合(一文搞定)

news2024/10/6 14:24:01

文章目录

  • 前言
  • 一、开始准备
    • 1. 包管理和安装chrome驱动
    • 2. 爬虫项目的创建(举个栗子)
    • 3. setting.py的配置
  • 二、代码演示
    • 1. 主爬虫程序
    • 2. 中间件的配置
    • 3. 定义item对象
    • 4. 定义管道
  • 总结


前言

scrapy和selenium的整合使用
先定个小目标实现万物皆可爬!我们是用scrapy框架来快速爬取页面上的数据,它是自带并发的,速度是可以的。但是一些ajax异步的请求我们不能这么爬取。我们要视同selenium来进行lazy loading,也就是懒加载,渲染到页面加载数据。


一、开始准备

爬取流程图

1. 包管理和安装chrome驱动

首先你要安装以下包:

pip install scrapy
pip install selenium == 3.0.0
pip install pymysql
pip install bs4
  • selenium新版本有bug,用3.0的版本。
  • chrome驱动的exe执行文件,放到你项目的根目录即可。下载地址:驱动

2. 爬虫项目的创建(举个栗子)

  1. 创建项目
scrapy startproject cnki
  1. 您爬取的目标网站
scrapy genspider cnki https://www.cnki.net
  1. 运行爬虫
# 运行不导出(一般在pipelines做导出操作)
scrapy crawl cnki
# 针对不同的选择可以导出为xlsx、json等格式文件
scrapy crawl demo -o demo.csv

3. setting.py的配置

  1. 配置数据源,如下:
DB_HOST = 'localhost'
DB_PORT = 3306
DB_USER = 'root'
DB_PASSWORD ='123456'
DB_DATABASE = 'spider'
  1. 防止打印log日志信息
LOG_LEVEL = 'WARNING'
  1. 配置USER_AGENT(浏览器控制台找一个)
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
  1. 配置DEFAULT_REQUEST_HEADERS(浏览器控制台找一个)
{
 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
 'Accept-Language': 'en',
}
  1. 随机延迟
DOWNLOAD_DELAY = 3
RANDOMIZE_DOWNLOAD_DELAY=True
  1. 中间件权重配置(这些中间件给他打开 并且按照项目实际需求配置权重,越小越先执行)
SPIDER_MIDDLEWARES # 蜘蛛中间件
DOWNLOADER_MIDDLEWARES # 下载中间件
ITEM_PIPELINES # 管道

二、代码演示

1. 主爬虫程序

  1. 初始化selenium (如果您不需要selenium,可以忽略这个
def __init__(self, *args,**kwargs):
    option = webdriver.ChromeOptions()  # 实例化一个浏览器对象
    option.add_argument('--headless')  # 添加参数,option可以是headless,--headless,-headless
    self.driver = webdriver.Chrome(options=option)  # 创建一个无头浏览器
    # self.driver = webdriver.Chrome()  # 创建一个无头浏览器
    time.sleep(3)
    super(CnkiSpider, self).__init__(*args, **kwargs)
    dispatcher.connect(self.close_driver,signals.spider_closed)
  1. 定义开始请求页面
    下面我只放了一个url,其实可以定义一组的然后进行遍历(一般是分页url使用)
    还有cookie、代理也可以在这里配置,详情请看进去看源码
    (不过一般在中间件配置)
def start_requests(self):
    for url in self.start_urls:
    	yield scrapy.Request(
                # 这里可以设置多个页面,一般用于分页的
                url=url,
            )
  1. 关闭selenium(一定要关掉)
def close_driver(self):
    print("爬虫正在退出,执行关闭浏览器哦")
    time.sleep(2)
    self.driver.quit()
  1. 解析页面
    这里就不多说,八仙过海各显神通
def parse(self,response: HtmlResponse):
sel = Selector(response)
dds = sel.css('.journal > .main-w1 > dl > dd')
for dd in dds:
	title = dd.css('h6 > a::attr(title)').extract_first()
    link = dd.css('h6 > a::attr(href)').extract_first()
    link = response.urljoin(link)
    author = dd.css('.baseinfo > span > #author::attr(title)').extract_first()
    abstract = dd.css('.abstract::text').extract_first()
    count = dd.css('.opts > .opts-count > li > em::text').extract_first()
    count = int(count)
    date = dd.css('.opts > .opts-count > .date::text').extract_first()
    date = date.split(':')[1]
    date = datetime.datetime.strptime(date,"%Y-%m-%d")
    rc = Recommend()
    rc['title'] = title
    rc['link'] = link
    rc['author'] = author
    rc['abstract'] = abstract
    rc['count'] = count
    rc['date'] = date
    yield rc

这里要注意我们yield可以返回不仅是item,也可以是Request,进行页面详情的请求(套娃)

yield Request(
     url=link, # 这是上面页面上的链接,用来进一步请求
     callback=self.parse_detail, # 这是回调函数
     cb_kwargs={'item':rc} # 这是把上面的item传递下来
   )

2. 中间件的配置

  1. 针对selenium
    没有selenium请忽略
class SeleniumDownloaderMiddleware:
    def process_request(self, request , spider):
        if spider.name == 'cnki':
            spider.driver.get(request.url)
            time.sleep(2)
            print(f"当前访问{request.url}")
            spider.driver.refresh()
            time.sleep(3)
            return HtmlResponse(url=spider.driver.current_url,body=spider.driver.page_source,encoding='utf-8')
  1. SpiderMiddleware保持默认配置即可
  2. DownloaderMiddleware可以配置cookie和代理之类的。如:
# 我自定义的解析cookie方法
def get_cookie_dict():
    cookie_str = 填上你的cookie
    cookie_dict = {}
    for item in cookie_str.split(';'):
        key, value = item.split('=',maxsplit=1)
        cookie_dict[key] = value
    return cookie_dict
COOKIES_DICT = get_cookie_dict()
	# 这是DownloaderMiddleware这是自带的方法哈
def process_request(self, request : Request, spider):
    request.cookies = COOKIES_DICT
    return None

3. 定义item对象

用来接受爬虫到的数据

class Recommend(scrapy.Item):
    title = scrapy.Field()
    author = scrapy.Field()
    abstract = scrapy.Field()
    link = scrapy.Field()
    count = scrapy.Field()
    date = scrapy.Field()

4. 定义管道

实现对数据库的导入(你也可以写excel的)

class RecommendPipeline:
    @classmethod
    def from_crawler(cls, crawler: Crawler):
        host = crawler.settings['DB_HOST']
        port = crawler.settings['DB_PORT']
        username = crawler.settings['DB_USER']
        password = crawler.settings['DB_PASSWORD']
        database = crawler.settings['DB_DATABASE']
        return cls(host, port, username, password, database)

    def __init__(self, host, port, username, password, database):
        # 1、与数据库建立连接
        self.conn = pymysql.connect(host=host, port=port, user=username, password=password, database=database,
                                    charset='utf8mb4')
        # 2、创建游标
        self.cursor = self.conn.cursor()

        # 3、批处理需要的容器
        self.data = []

    def process_item(self, item, spider):
        title = item.get('title', '')
        author = item.get('author', '')
        abstract = item.get('abstract', '')
        link = item.get('link', '')
        count = item.get('count', '')
        date = item.get('date', '')
        # 如果要实现批处理:
        self.data.append((title,author,abstract,link,count,date))
        # 如果存够了10条就进数据库
        if len(self.data) == 10:
            self._to_write_db()
            # 然后再清空
            self.data.clear()
        return item

    def close_spider(self, spider):
        # 如果最后不满足10条
        if len(self.data) > 0:
            self._to_write_db()
        self.conn.close()

    def _to_write_db(self):
        # 作为一个实时的推荐,我希望将查到的数据作为一个temp
        # 'delete from tb_recommend where 1 = 1' 删除满,并且主键自增不会从1开始
        self.cursor.execute(
            'truncate table tb_recommend'
        )
        self.cursor.executemany(
            'insert into tb_recommend (title,author,abstract,link,count,date) values (%s, %s, %s, %s, %s, %s)',
            self.data
        )
        self.conn.commit()

记得写入setting.py,设置其权重。
*接下来您就可以按照这种方法‘愉’ ‘快’的进行爬虫啦!!! *

总结

这是scrapy和selenium的具体整合使用,scrapy框架的内容还有很多方法还没用到,都有待开发。其次就是selenium的填充之类的操作还没有使用,还需要去复习selenium的api。

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

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

相关文章

Loadrunner结合Fiddler实现脚本的录制

Loadrunner一直被业内认为是最好用的性能测试工具,行业大哥大, 但是用过Loadrunner的朋友都知道,工具功能的确牛,但实际使用过程中总会有一些困扰新手的问题,无法录制脚本, 如遇到Loadrunner不支持的IE版本、对Chrome、…

【C语言】Sleep()函数----详解

🍁 博客主页:江池俊的博客 🍁收录专栏:C语言——探索高效编程的基石 🍁 如果觉得博主的文章还不错的话,请点赞👍收藏🌟 三连支持一下博主💞 目录 前言 📌C语言sleep函…

一本通1919:【02NOIP普及组】选数

这道题感觉很好玩。 正文: 先放题目: 信息学奥赛一本通(C版)在线评测系统 (ssoier.cn)http://ybt.ssoier.cn:8088/problem_show.php?pid1919 描述 已知 n 个整数 x1,x2,…,xn,以及一个整数 k(k&#…

Docker 容器生命周期:创建、启动、暂停与停止----从创建到停止多角度分析

🌷🍁 博主 libin9iOak带您 Go to New World.✨🍁 🦄 个人主页——libin9iOak的博客🎐 🐳 《面试题大全》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~&#x1f33…

Vuex基本使用

目录 一、什么是vuex二、什么时候使用 Vuex三、Vuex 工作原理图四、vuex 核心概念和 API4.1 state4.2 actions4.3 mutations4.4 getters 五、代码生成器5.1 mapGetters5.2 mapState5.3 mapActions5.4 mapMutations 六、vuex模块化编码七、求和案例 一、什么是vuex 专门在 Vue …

文本生成人工评价指标及一致性校验方法总结(附代码实现)

前言:人工评估( Manual Evaluation / Human Evaluation)是文本生成工作评估中非常重要的一环。在对模型的文本生成质量进行评估时,除客观的自动评价指标,还需有人工评价指标的主观判断,综合二者的结果完成评…

zabbix监控自己

目录 一、实验环境准备 二、server端 1、配置阿里云yum源 2、部署lamp环境 3、启动lamp对应服务 4、准备java环境 5、源码安装zabbix 6、mariadb数据库授权 7、创建zabbix程序用户并授权防止权限报错 8、修改zabbix配置文件 9、配置php与apache 10、web安装zabbix …

[回馈]ASP.NET Core MVC开发实战之商城系统(开篇)

在编程方面,从来都是实践出真知,书读百遍其义自见,所以实战是最好的提升自己编程能力的方式。 前一段时间,写了一些实战系列文章,如: ASP.NET MVC开发学生信息管理系统VueAntdvAsp.net WebApi开发学生信息…

地摊盛行,VR全景如何帮助实体餐饮商家人气翻倍?

“民以食为天”,餐饮行业始终在市场经济中扮演着重要角色,前有“淄博烧烤火爆出圈”,后有“地摊经济夜市亮相”,可以看到餐饮行业呈现出市场广阔、高频刚需、标准化程度低的特点。但是地摊经济的盛行,让很多实体餐饮商…

【漏洞修复】node-exporter被检测/debug/vars泄漏信息漏洞

node-exporter被检测/debug/vars泄漏信息漏洞 漏洞说明修复方法 漏洞说明 和之前的pprof类似,都是国产的安全工具扫出来的莫名其妙的东西,这次也是报的node-exporter存在这个漏洞,又归我处理。当访问node-exporter的/debug/vars路由时能获取…

Ubuntu22.04下安装Ros2-Humble

ROS2的Humble版本为TLS版本,维护日期截止到2027年(可以参考这里确查看Humble和Ubuntu系统的关系) 可以看到,其支持Linux/MacOS/Windows等多个系统,针对于Linux系统,对应的系统版本是(Ubuntu 22.04&#xff…

el-checkbox获取选中的id

获取选中checkbox的label和value <el-checkbox-group v-model="checkedAlarmObj"><el-checkbox @change="changeObj" v-for="item in alarmObj" :label="item.roleName" :key="item.roleId":value="…

断路器绝缘电阻试验

断路器 绝缘电阻试验 试验目的 检验断路器合闸后灭弧室、 主绝缘和提升杆是否发生受潮&#xff0c; 劣化变质等缺陷。 试验设备 绝缘电阻测试仪 厂家&#xff1a; 湖北众拓高试 试验接线 相对地 端口间 试验步骤 真空断路器本体与断口的绝缘电阻 试验前对兆欧表本身进行检…

2023年了,为何 Selenium 依然这么火?

今天给大家带来的主题是自动化测试框架Selenium&#xff0c;话不多说&#xff0c;直接开始&#xff01; 1.什么是 Selenium 自动化测试 Jason Huggins 于 2004 年创建了一个 JavaScript 框架&#xff0c;旨在将其从重复的手动测试中解放出来。 最初命名为 JavaScriptTestRunn…

grafana备份脚本

备份思路 1、逐个dashboard备份配置 2、每个dashboard保存成一个文件 3、文件名定义为 目录名-dashboard名.json 4、使用python2 5、其中http_header中生成的Authorization API KEY已过期&#xff0c;请自己重新生成后替换使用。 6、保存文件部分适配的是windows&#xf…

使用IDEA构建jar然后转执行程序exe的爬坑

https://download.csdn.net/download/leoysq/87939492 构建jar

【矩阵的创建与基本运算】——matlab基础

目录索引 创建矩阵&#xff1a;zeros()&#xff1a;ones&#xff1a;eye()&#xff1a;magic()&#xff1a;引号创建序列矩阵&#xff1a; 加减与数乘&#xff1a;其他运算&#xff1a;指数运算&#xff1a;*exp()&#xff1a;* 点式运算&#xff1a; 创建矩阵&#xff1a; 如…

同心筑梦 展翅翱翔 | 2023届GBASE新员工筑梦计划培训报道

为帮助新入职员工增进彼此了解&#xff0c;快速融入GBASE大家庭中&#xff0c;激发大家工作热情&#xff0c;为此设计了拓展训练课程。完成“抓住机遇&#xff0c;摆脱困境”“蛟龙出海”“破冰”等环节后&#xff0c;新员工们已完全没有开始时的紧张&#xff0c;在全新的环境中…

MyBatis的相关api

1. MyBatis的相关api 1.1 Resources org.apache.ibatis.io.Resources&#xff1a;加载资源的工具类。 核心方法 返回值方法名说明InputStreamgetResourceAsStream(String fileName)通过类加载器返回指定资源的字节流 1.2 构建器SqlSessionFactoryBuilder 建造者设计模式&…

思维决定发展,测试人也不例外

最近特别懒&#xff0c;不想码字&#xff0c;原本写作就很差&#xff0c;更是退化严重。社招和校招面试过很多人&#xff0c;从十年前自己还很弱的时候学着面试&#xff0c;到数百次面试积累之后&#xff0c;面对候选人的时候&#xff0c;我的内心依然有些许紧张&#xff0c;非…