scrapy 使用Selenium与Scrapy处理动态加载网页内容的解决方法

引言
在爬虫技术领域,处理动态加载的网页内容常常是一项挑战,尤其是对于那些通过用户滚动或其他交互动态加载更多内容的网站。本文将介绍如何结合使用Selenium和Scrapy来有效处理这类网页。

初探Selenium与Scrapy的结合
首先,我们探索如何使用Selenium在Scrapy中间件中处理动态加载内容的网页。关键在于模拟用户滚动行为,以加载并捕获所有内容。

# Define here the models for your spider middleware
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/spider-middleware.htmlfrom scrapy import signals
from scrapy.http import HtmlResponse
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager
import random,time
from fake_useragent import UserAgent
# useful for handling different item types with a single interface
from itemadapter import is_item, ItemAdapter
from scrapy.utils.project import get_project_settingsclass SeleniumMiddleware:@classmethoddef from_crawler(cls, crawler):middleware = cls()crawler.signals.connect(middleware.spider_closed, signal=signals.spider_closed)return middlewaredef __init__(self):options = Options()# options.add_argument('--headless')  # 启用无头模式# options.add_argument('user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36')# 创建UserAgent对象# ua = UserAgent()# settings=get_project_settings() #获取settings配置,设置需要的信息# 生成随机User-Agent 没有用这里是因为这里有可能会产生手机端的访问方式# user_agent = ua.random# user_agent = random.choice(settings["USER_AGENTS"])user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"# print("user_agent:",user_agent)options.add_argument('--disable-blink-features=AutomationControlled')#关闭自动控制blink特征options.add_argument(f"user-agent={user_agent}")options.add_experimental_option('excludeSwitches', ['enable-automation'])self.driver = webdriver.Chrome(options=options)def spider_closed(self, spider):self.driver.quit()def process_request(self, request, spider):self.driver.get(request.url)# 等待页面初步加载完成time.sleep(3)  # 示例等待时间,可能需要根据实际页面调整# 找到以游客模式进入的按钮try:element = self.driver.find_element(By.ID,"loginContainer")child_element = self.driver.find_elements(By.CLASS_NAME,'css-txolmk-DivGuestModeContainer')child_element[0].click()except Exception as e:print("以游客模式进入的按钮没有找到")time.sleep(3)try:flush_element = self.driver.find_elements(By.CLASS_NAME,'css-z9i4la-Button-StyledButton')flush_element[0].click()except Exception as e:print("刷新按钮没有找到")time.sleep(6)xunhuan = Truetemp_height = 0while xunhuan:self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")time.sleep(2)# 获取当前滚动条距离顶部的距离check_height = self.driver.execute_script("return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;")if check_height == temp_height:print("到底了")xunhuan = Falseelse:temp_height = check_heightbody = self.driver.page_source.encode('utf-8')return HtmlResponse(self.driver.current_url, body=body, encoding='utf-8', request=request)

完整的Scrapy爬虫实例
下面是一个使用Selenium和Scrapy爬取tiktok视频播放量的示例。

import scrapy,json,html,base64
import datetime,hashlib
from tiktokSelenium.items import TiktokseleniumItemclass TiktokSpider(scrapy.Spider):name = "tiktok"# allowed_domains = ["httpbin.org"]# start_urls = ["https://httpbin.org/user-agent"]allowed_domains = ["tiktok.com"]start_urls = ["https://www.tiktok.com/@espn"]def __init__(self):# settings=get_project_settings() #获取settings配置,设置需要的信息# self.tik_accounts = settings['TIK_ACCOUNTS']# 获取今天的爬取# self.fenrundate = time.strftime("%Y%m%d")# 获取今天的爬取self.fenrundate = self.get_yesterday_day()def parse(self, response):print("==================response.text=======================")# print(response.text)print(len(response.xpath('//div[@class="css-x6y88p-DivItemContainerV2 e19c29qe8"]')))author_url = response.urlauthor_name = author_url.split("@")[-1]for sel in response.xpath('//div[@class="css-x6y88p-DivItemContainerV2 e19c29qe8"]'):link = sel.xpath('div/div/div/a')[0]# 获取视频的链接地址href = sel.xpath('div/div/div/a/@href').extract_first()# 视频idvid = href.split("/")[-1]vclick = link.xpath('div/div/strong[@class="video-count css-dirst9-StrongVideoCount e148ts222"]/text()').extract_first()# vclick = videoCount[0].texttitle = html.escape(sel.xpath('div[2]/div/@aria-label').extract_first())# continueuqc_arr = [title,vclick]cvideo_item = TiktokseleniumItem()# cvideo_item = {}cvideo_item['author_url'] = author_urlcvideo_item['author_name'] = author_namecvideo_item['video_id'] = vidcvideo_item['video_url'] = hrefcvideo_item['video_title'] = titlecvideo_item['video_hits'] = vclickcvideo_item['date'] = self.fenrundatecvideo_item['video_real_hits'] = self.convert_to_real_hits(vclick)# print(cvideo_item)cvideo_item['unique_key'] = self.str_md5("_".join(uqc_arr))yield cvideo_item     # print(cvideo_item)# 获取昨天的日期 def get_yesterday_day(self):today = datetime.date.today()yesterday = today - datetime.timedelta(days=1)yesterday2 = str(yesterday)return yesterday2.replace("-","")# 点击量转化为数字def convert_to_real_hits(self,strs):lastItem = strs[-1]if lastItem in ['K','M','B','k','m','b']:strs = eval(strs[0:-1])if lastItem == 'K' or lastItem == 'k':strs = strs * 1000elif lastItem == 'M' or lastItem == 'm':strs = strs * 1000 * 1000else:strs = strs * 1000 * 1000 * 1000return int(strs)def str_md5(self,strs):m = hashlib.md5()bs = base64.b64encode(strs.encode("utf-8"))m.update(bs)str_md5 = m.hexdigest()return str_md5

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

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

相关文章

1.微信小程序开发之准备工作

1.微信小程序账号注册 小程序开发 与 网页开发不一样,在开始微信小程序开发之前,需要访问 微信公众平台,注册一个微信小程序账号。 在拥有了小程序的账号以后,我们才可以开发和管理小程序,后续可以通过该账号进行开发…

springboot分页

1.代码分页 List<TbAjltData> pageViewList list.stream().skip((pageDomain.getPageNum() - 1) * pageDomain.getPageSize()).limit(pageDomain.getPageSize()).collect(Collectors.toList());2. Overridepublic List<TbAjk> selectTbAjkList(TbAjk tbAjk, Pag…

国网电力分公司、税务企业如何向央媒投稿?

税务、电力、银行等单位如果想要将稿件发布到中央媒体&#xff0c;可以遵循为大家整理的以下步骤和建议&#xff1a; 了解央媒的定位与要求&#xff1a;中央媒体&#xff0c;如新华社、人民日报、中央电视台等&#xff0c;都有其独特的报道风格和关注重点。在投稿前&#xff0…

【Web后端】会话跟踪技术及过滤器

1.会话跟踪技术 1.1 会话的概念 在web应用中&#xff0c;浏览器和服务器在一段时间内发送请求和响应的连续交互的全过程 1.2 会话跟踪概念 对同一个用户跟服务器的连续请求和接收响应的监视过程 1.3 会话跟踪作用 浏览器和服务器是以http协议进行通信&#xff0c;http协议是…

SD1005S控制电路LED光源恒流控制模块驱动放大器

SD1005S是一个集控制电路与发光电路于一体的智能外控LED光源。其外型与一个5050LED灯珠相同,每个 元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大驱动电路&#xff0c;防反接电路&#xff0c;还包含有 高精度的内部振荡器和高精度恒流控制模块&#xf…

LM3658单芯片充电器电源适配器50mA-1000mA充电电流

该LM3658是一个单芯片充电器IC专为手持应用。它 可以通过AC电源适配器或USB电源对单节锂离子/聚 合物电池进行安全充电和维护。USB/AC的输入电源 选择是自动的。两个电源同时存在时&#xff0c;交流电源优先 。当使用AC墙壁适配器时&#xff0c;充电电流通过外部电阻器 编程&am…

算法工程师面试问题 | YOLOv8面试考点原理全解析(一)

本文给大家带来的百面算法工程师是深度学习目标检测YOLOv8面试总结&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;我们还将介绍一些常见的深度学习目标检测面试问题&#xff0c;并提供参考的回答…

Vue中<style>标签的scoped属性

Vue中style标签的scoped属性 一、前言1、举例 二、总结 一、前言 scoped 是 Vue 中 <style> 标签的一个特殊属性&#xff0c;用于限定样式的作用范围。当你在 Vue 单文件组件&#xff08;.vue 文件&#xff09;中使用 <style scoped> 标签时&#xff0c;该样式只会…

树结构,JS某个节点的父节点 兄弟节点 以及子节点

获取某个节点的所有父节点: function getAllParentNodes(list, id) {for (let i in list) {if (list[i].id id) {return [list[i]].filter((v) > v.id ! id);}if (list[i].children?.length > 0) {let node getAllParentNodes(list[i].children, id);if (node) retur…

AWS RDS ElasticCache 监控可观测最佳实践

在当今的电子商务时代&#xff0c;一个高效、稳定的电商平台对于保持竞争力至关重要。数据库作为电商平台的核心支撑&#xff0c;其性能直接影响到用户体验和业务流畅度。本文将深入探讨如何在电商场景下通过观测云对亚马逊云科技 RDS&#xff08;MySQL&#xff09; 和 Elastic…

python+selenium - UI自动框架之封装log类

通过自定log类&#xff0c;能把执行过程记录到日志&#xff0c;方便检查和重现问题。 log类介绍&#xff1a; 每次调用log函数&#xff0c;会根据绝对路径生成日志文件在logs目录下面(在被调用的时候日志会输出到指定的文件&#xff09;&#xff0c;日志文件的格式是年月日.lo…

vue+element的表格(el-table)排班情况表(2024-05-09)

vueelement的表格&#xff08;el-table&#xff09;排班情况&#xff0c;增删查改等简单功能 代码&#xff1a; <template><!-- 表格 --><div class"sedules"><el-header><el-date-pickerv-model"monthValue2"type"month…

postgresql中控制符带来的数据错觉

简介 在数据库字符集中&#xff0c;由于数据质量的控制不够完善&#xff0c;每一个字符集都并不是所有字符的能看见&#xff0c;有些字符的展示可能会出现乱码&#xff0c;甚至出现不同字符展示成同样效果的可能&#xff0c;给开发人员造成分析错觉。 当数据库存入了控制符&am…

【Unity Shader入门精要 第7章】基础纹理(三)

1. 渐变纹理 另外一种对于纹理的使用方式是通过渐变纹理为物体提供漫反射光照效果。 顾名思义&#xff0c;渐变纹理本身就是一张颜色渐变&#xff08;可以是连续渐变&#xff0c;也可能是突变&#xff09;的图片&#xff0c;这个渐变的过程模拟的就是光源从不同的角度照射物体…

Win11下Java环境安装指南

Windows下Java环境安装指南 前言一、安装简介JDK与JRE安装包 二、JDK安装检查操作系统类型基于Win11基于Win10 安装包准备工作 三、配置环境配置JAVA_HOME配置Path配置CLASSPATH 四、检验配置是否打开cmd命令行窗口输出java -version命令 五、注意事项 前言 在Windows系统上安…

移动机器人的机动性

移动机器人的机动性 机器人底盘运动学的活动性是表示它在环境中直接运动的能力。限制活动性的基本约束是每一轮子必须满足它的滑动约束的规则。所以,我们可从方程(3.26)正式地推导机器人的活动性。 除了瞬时的运动学运动之外,移动机器人通过操纵可操纵的轮子,能够随时操纵它的…

基于springboot实现的教师人事档案管理系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&…

mysql 拆分字段为多行

留备 原数据idname1张三,李四,王二2zhangsan,lisi,wanger目标数据idname1张三1李四1王二2zhangsan2lisi2wanger select t.id, substring_index(substring_index(t.name,,,t1.help_topic_id1),,,-1) name from zq.test t inner join mysql.help_topic t1 on t1.he…

循环神经网络RNN的初学

1.循环神经网络的特点 x1——>y1的同时会产生a1&#xff0c;它包含了我们第一列处理信息的一些特点&#xff0c;然后这个a1就会被传送到y2上去&#xff0c;那么x2——>y2的序列中就会包含前一个的特点&#xff0c;依次类推&#xff0c;这就是我们的RNN结构**&#xff08…

八分钟“手撕”包装类与泛型

目录 一、包装类 基本数据类型和对应的包装类 装箱和拆箱 【思考题】 二、泛型 什么是泛型 引出泛型 怎么定义泛型和使用泛型 裸类型(Raw Type) 擦除机制 额外&#xff0c;注意下列代码&#xff1a; 泛型的上界 泛型的接口应用 泛型方法 一、包装类 简单来…