不会JS逆向也能高效结合Scrapy与Selenium实现爬虫抓取

1. 创建基础的scrapy项目

1.1 基础项目

  1. 在pycharm中安装scrapy框架

pip install scrapy

  1. 创建项目

scrapy startproject 项目名称

我们现在可以看到整体文件的目录:

firstBlood
├── firstBlood # 项目跟目录
│ ├── init.py
│ ├── items.py # 封装数据的格式
│ ├── middlewares.py # 所有中间件
│ ├── pipelines.py # 所有的管道
│ ├── settings.py # 爬虫配置信息
│ └── spiders # 爬虫文件夹, 稍后里面会写入爬虫代码
│ └── init.py
└── scrapy.cfg # scrapy项目配置信息

  1. 创建爬虫文件

cd firstBlood

  1. 创建主文件
scrapy genspider 爬虫文件的名称(自定义一个名字即可) 起始url (随便写一个网址即可)

比如:

scrapy genspider baidu www.baidu.com

1.2 修改配置文件

打开settings.py:

    • 不遵从robots协议:ROBOTSTXT_OBEY = False
    • 指定输出日志的类型:LOG_LEVEL = ‘ERROR’
    • 指定UA:USER_AGENT = ‘xxxxxx’

1.3 启动程序

scrapy crawl 文件名(我这里是baidu)

2. Scrapy + Selenium

我们现在来进行基础的数据采集,我这里准备采集有关“三只羊”的资讯信息和详情内容:
在这里插入图片描述

2.1 通过scrapy异步爬取url

主文件baidu.com:

import scrapy
from ..items import FirstItemclass BaiduSpider(scrapy.Spider):name = "baidu"allowed_domains = ["www.baidu.com"]start_urls = ['http://www.baidu.com/s?ie=utf-8&medium=0&rtt=1&bsst=1&rsv_dl=news_t_sk&cl=2&wd=%E4%B8%89%E5%8F%AA%E7%BE%8A&tn=news&rsv_bp=1&oq=&rsv_sug3=12&rsv_sug1=5&rsv_sug7=101&rsv_sug2=0&rsv_btype=t&f=8&inputT=1395&rsv_sug4=1395']def parse(self, response):text = response# 获取数据contents = text.xpath('//a[@class="news-title-font_1xS-F"]')for c in contents:url = c.xpath('@href').extract_first()title = c.xpath('@aria-label').extract_first()items = FirstItem()items['url'] = urlitems['title'] = titleyield scrapy.Request(url=url, callback=self.detail_parse, meta={'item': items})def detail_parse(self, response):print(response)

items:

import scrapyclass FirstItem(scrapy.Item):url = scrapy.Field()title = scrapy.Field()

2.2 中间件结合selenium

假设现在,详情页面是涉及到js加密的,这该如何解决呢?

聪明的小伙伴已经想到了:是selenium!

只要模拟的好,所见即所得

那么我们该如何做呢?

众所周知,在Scrapy框架中,有一种名叫中间件的东西,他有什么用呢:

此中间件可以在请求之前、响应之前截取请求/响应信息,并在此做一系列操作

也就是说,在返回给detail_parse之前,我们可以重新处理响应数据

来看代码:

baidu.py

class BaiduSpider(scrapy.Spider):name = "baidu"# allowed_domains = ["www.baidu.com"]start_urls = ['http://www.baidu.com/s?ie=utf-8&medium=0&rtt=1&bsst=1&rsv_dl=news_t_sk&cl=2&wd=%E4%B8%89%E5%8F%AA%E7%BE%8A&tn=news&rsv_bp=1&oq=&rsv_sug3=12&rsv_sug1=5&rsv_sug7=101&rsv_sug2=0&rsv_btype=t&f=8&inputT=1395&rsv_sug4=1395']# 实例化浏览器对象bro = webdriver.Chrome()def parse(self, response):text = response# 获取数据contents = text.xpath('//a[@class="news-title-font_1xS-F"]')items = FirstItem()for c in contents:url = c.xpath('@href').extract_first()title = c.xpath('@aria-label').extract_first()items['url'] = urlitems['title'] = titleyield scrapy.Request(url=url, callback=self.detail_parse, meta={'item': items} ,  dont_filter=True)def detail_parse(self, response):item = response.meta['item']content = response.xpath('//div[@class="EaCvy"]//text()').extract_first()item['content'] = contentyield item# 重写父类方法def closed(self, spider):print('整个操作结束!!!')self.bro.quit()

重点:

  1. bro = webdriver.Chrome()这里实例化了一个浏览器对象

  2. 这里是解析完url后,再一次手动发起请求

yield scrapy.Request(url=url, callback=self.detail_parse, meta={'item': items} ,  dont_filter=True)
  1. 这是重写的父类方法
    def closed(self, spider):print('整个操作结束!!!')self.bro.quit()  # 执行完就关闭浏览器

最重要的是中间件的写法:

pipelines.py

import time
from scrapy import signals
from itemadapter import is_item, ItemAdapter
from scrapy.http import HtmlResponse
class FirstDownloaderMiddleware:def process_request(self, request, spider):  # 这里的spider就是指的主对象程序,也就是前面发出请求的类对象return Nonedef process_response(self, request, response, spider):# 第一次请求不触发seleniumif request.url != spider.start_urls[0]:bro = spider.bro  # selenium浏览器对象bro.get(request.url)time.sleep(3)source = bro.page_source# 重新封装一个响应对象new_response = HtmlResponse(url=request.url, body=source, request=request, encoding='utf-8')return new_responsereturn response

items.py

import scrapy
class FirstItem(scrapy.Item):url = scrapy.Field()title = scrapy.Field()content = scrapy.Field()

3. 总结

其实想要实现scrapy和selenium共同完成爬虫任务还是比较简单的。

最重要的是理解中间件的性质,并且能够在合适的地方去修改请求/响应内容。

在遇到比较复杂的页面时,可以尝试使用scrapy + selenium的模式进行爬取。

将两者结合使用,能够弥补彼此的不足,发挥出更大的优势。

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

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

相关文章

【网络】高级IO——select版本TCP服务器

目录 前言 一,select函数 1.1.参数一:nfds 1.2.参数二: readfds, writefds, exceptfds 1.2.1.fd_set类型和相关操作宏 1.2.2.readfds, writefds, exceptfds 1.2.3.怎么理解 readfds, writefds, exceptfds是输入输出型参数 1.3.参数三…

数据结构之二叉树遍历

二叉树的遍历 先序遍历 先输入父节点,再遍历左子树和右子树:A、B、D、E、C、F、G 中序遍历 先遍历左子树,再输出父节点,再遍历右子树:D、B、E、A、F、C、G 后序遍历 先遍历左子树,再遍历右子树,…

SpringBoot设置mysql的ssl连接

因工作需要,mysql连接需要开启ssl认证,本文主要讲述客户端如何配置ssl连接。 开发环境信息: SpringBoot: 2.0.5.RELEASE mysql-connector-java: 8.0.18 mysql version:8.0.18 一、检查服务端是否开启ssl认…

微信公众号开发入门

微信公众号开发是指开发者基于微信公众平台(WeChat Official Accounts Platform)所提供的接口与功能,开发和构建自定义的功能与服务,以满足企业、组织或个人在微信生态中的应用需求。微信公众号开发主要围绕公众号消息处理、菜单管…

K1计划100%收购 MariaDB; TDSQL成为腾讯云核心战略产品; Oracle@AWS/Google/Azure发布

重要更新 1. 腾讯全球数字生态大会与9月5日-6日举行,发布“5T”战略,包括TDSQL、TencentOS、TCE(专有云 )、TBDS(大数据)、TI (人工智能开发平台)等 ( [2] ) ; 并正式向原子开源基金…

初始分布式系统和Redis特点(

(一)认识redis Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperlog…

后台数据管理系统 - 项目架构设计-Vue3+axios+Element-plus(0920)

十三、文章分类页面 - [element-plus 表格] Git仓库:https://gitee.com/msyycn/vue3-hei-ma.git 基本架子 - PageContainer 功能需求说明: 基本架子-PageContainer封装文章分类渲染 & loading处理文章分类添加编辑[element-plus弹层]文章分类删除…

[Python]案例驱动最佳入门:Python数据可视化在气候研究中的应用

在全球气候问题日益受到关注的今天,气温变化成为了科学家、政府、公众讨论的热门话题。然而,全球气温究竟是如何变化的?我们能通过数据洞察到哪些趋势?本文将通过真实模拟的气温数据,结合Python数据分析和可视化技术&a…

Flutter启动无法运行热重载

当出现这种报错时,大概率是flutter的NO_Proxy出问题。 请忽略上面的Android报错因为我做的是windows开发这个也就不管了哈,解决下面也有解决报错的命令大家执行一下就行。 着重说一下Proxy的问题, 我们看到提示NO_PROXY 没有设置。 这个时候我…

基于YOLOv8+LSTM的商超扶梯场景下行人安全行为姿态检测识别

基于YOLOv8LSTM的商超扶梯场景下行人安全行为姿态检测识别 手扶电梯 行为识别 可检测有人正常行走,有人 跌倒,有人逆行三种行为 跌倒检测 电梯跌倒 扶梯跌倒 人体行为检测 YOLOv8LSTM。 基于YOLOv8LSTM的商超扶梯场景下行人安全行为姿态检测识别&#xf…

Vue3.0组合式API:使用ref获取DOM元素

Vue3.0组合式API系列文章: 《Vue3.0组合式API:setup()函数》 《Vue3.0组合式API:使用reactive()、ref()创建响应式代理对象》 《Vue3.0组合式API:computed计算属性、watch监听器、watchEffect高级监听器》 《Vue3.0组合式API&…

【贪心算法】贪心算法一

贪心算法一 1.柠檬水找零2.将数组和减半的最少操作次数3.最大数4.摆动序列 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃😃 1.柠檬水找零 题目…

【Linux】【Vim】Vim 基础

Vim/Gvim 基础 文本编辑基础编辑操作符命令和位移改变文本重复改动Visual 模式移动文本(复制、粘贴)文本对象替换模式 光标移动以 word 为单位移动行首和行尾行内指定单字符移动到匹配的括号光标移动到指定行滚屏简单查找 /string标记 分屏vimdiff 文本编辑 基础编辑 Normal 模…

Gitlab runner的使用示例(二):Maven + Docker 自动化构建与部署

Gitlab runner的使用示例(二):Maven Docker 自动化构建与部署 在本篇文章中,我们将详细解析一个典型的 GitLab CI/CD 配置文件(gitlab-ci.yml),该文件主要用于通过 Maven 构建 Java 应用&…

07_Python数据类型_集合

Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 集合 集合(set)是Python中一个非常强大的数据类型,它存储的是一组无序且不重复的元素,集合中的元素必须…

Games101学习 - 着色

本文主要讲述Games101中的着色部分。 文中将使用UE的UTexture2D接口,若不了解可以看这篇: https://blog.csdn.net/grayrail/article/details/142165442 1.面积比计算三角形坐标 通过三角形面积比可以得到三角形的坐标alpha、beta、gamma从而进行插值&a…

AI技术好书推荐:《AI系统-原理与架构》

今年1月份在B站发现了一个B站宝藏博主,发布的一系列AI技术类科普视频内容很干,逻辑清晰,很多知识点讲的深入浅出,非常有用,被直接种粉。 后来这一系列的课程内容博主有了出书的计划,机缘巧合有幸参与部分章…

CSS入门笔记

目录 概述 组成 CSS 语法 常见的使用方式 CSS 优先级 CSS 选择器 1. 基本选择器 2. 属性选择器 3. 伪类选择器 4. 组合选择器 示例 优先级 边框样式与盒子模型 单个边框 边框轮廓(Outline) 盒子模型 模型介绍 边距设置 布局示例 文…

计算机考研408-计算机网络

【题33】下列选项中,不属于网络体系结构所描述的内容是() A.网络的层次 B.每一层使用的协议 C.协议的内部实现细节 D.每一层必须完成的功能 解析: 本题考查的是网络体系结构相关的概念。 图1描述了网络的7层架构以及每一层所要完成…

Python模块和包:标准库模块(os, sys, datetime, math等)②

文章目录 一、os 模块1.1 获取当前工作目录1.2 列出目录内容1.3 创建和删除目录1.4 文件和目录操作 二、sys 模块2.1 获取命令行参数2.2 退出程序2.3 获取 Python 版本信息 三、datetime 模块3.1 获取当前日期和时间3.2 日期和时间的格式化3.3 日期和时间的运算 四、math 模块4…