CrawlSpider【获取当前访问链接的父链接和锚文本】代码逻辑

tip: 超链接对应的文案通常被称为“锚文本”(anchor text)

在继承CrawlSpider父类的前提下,编写一个 fetch_referer 方法获取当前response.url的父链接和锚文本。 

实现逻辑,通过一个例子简要说明:

  1. 如果设置 start_url="www.baidu.com", Rule(LinkExtractor())匹配链接的规则是任何链接。 
  2. 那么第一个为 response.url="www.baidu.com",假设 www.baidu.com 的response的页面源码存在链接 www.ibaidu.com, www.etbaidu.com;那么此时 refere_extract_link = {"www.baidu.com": ["www.ibaidu.com","www.etbaidu.com"]};进入for循环判断,因为 response.url="www.baidu.com"不匹配list的links ["www.ibaidu.com","www.etbaidu.com"] 的任何一个,所以链接 www.baidu.com 的父链接 referer_url 和 锚文本 referer_url_text 都为None。
  3. scrapy CrawlSpider会将links的链接继续提交给下载器访问,response.url 重新被赋值为 response.url = "www.ibaidu.com",假设 www.ibaidu.com 的response的页面源码存在链接 "www.ibaidu_child.com","www.ibaidu_second.com";那么此时 refere_extract_link = {"www.baidu.com": ["www.ibaidu.com","www.etbaidu.com"], "www.ibaidu.com": ["www.ibaidu_child.com","www.ibaidu_second.com"]};进入for循环判断,因为 response.url="www.ibaidu.com" 匹配list的links ["www.ibaidu.com","www.etbaidu.com"] 的"www.ibaidu.com",而该list的key是 www.baidu.com,所以链接 www.ibaidu.com 的父链接 referer_url = “www.baidu.com”, 锚文本referer_url_text = "百度一下,你就知道"。
  4.  其它链接重复步骤3,最后把所有链接的父链接和锚文本存储到itme里面。

完整代码:

from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from developer_docs_scrapy.items import DeveloperDocsScrapyItem
from helpers.operate_redis import operate_redis# 从redis获取配置
env_config = operate_redis().env_redis_config()
print(env_config)class DeveloperDocsSpider(CrawlSpider):name = env_config["spider_name"]  # "developer-docs"allowed_domains = [env_config["spider_allowed_domains"]]  # ["org.com"]start_urls = [env_config["spider_start_urls"]]  # ["https://developer.org.com/docs-service/"]# allow: 满足括号中的're'表达式的url会被提取,如果为空,则全部匹配# deny: 满足括号中的're'表达式的url不会被提取,优先级高于allow# deny要放在同一个linkextrator里面,不然,其它link规则会爬取deny的链接# 为了过滤非文档中心的链接,如:网页存在大量的org.com域名的新闻页面,所以,设置爬取规则:# 允许爬取URL包含初始URL的链接,如:https://developer.org.com/docs-service/search-result/?keyword=API 包含 https://developer.org.com/docs-service/rules = [Rule(LinkExtractor(allow=(start_urls), deny=()), process_links="deal_links", callback="parse_item", follow=True),#  Rule(LinkExtractor(deny=r'knowledge'))  ]# 从link_extractor中获取到链接列表时将会调用该函数。该方法主要用来过滤。或者对获取的url进行修改后再进行请求下载def deal_links(self, links):print("deal_links")for link in links:print(link, link.url, link.text)# 修改link的url# link.url = link.url.resplace("","").replace("","")return linksrefere_extract_link = {}def parse_item(self, response):item = DeveloperDocsScrapyItem()item["url"] = response.url# 从redis读取需要匹配元素xpath路径# redis读取的是str的列表,用eval转成list类型title_xpaths = eval(env_config["title_xpaths"])for xpath in title_xpaths:# 获取链接访问后的response获取的xpath内容selected_titles = response.xpath(xpath).extract()# 如果不为空,则存储改内容且退出当前for循环,不执行else内容if selected_titles:item["title"] = selected_titles[0]break# 如果for循环所有list后,selected_titles都为空,则执行elseelse:item["title"] = Nonereferer_url, referer_url_text = self.fetch_referer(response=response)item["referer_url"] = referer_urlitem["referer_url_text"] = referer_url_textyield itemdef fetch_referer(self,response):"""获取跳转到 response.url 的父链接 referer_url 和 父链接的文案 referer_url_text"""# 获取url访问后的response里面的链接(从源码中摘取部分)seen = set()for rule_index, rule in enumerate(self._rules):links = [# 提取 response.url的页面的 链接+【链接文案】存储在listlnk.url + "【" + lnk.text + "】" for lnk in rule.link_extractor.extract_links(response) if lnk not in seen]# print(response.url, links)# 把每一个链接访问后的页面获取到的链接组成 key: list 存储到 refere_extract_linkself.refere_extract_link.update({response.url: links})# print(self.refere_extract_link)# 判断每一个response.url是否在refere_extract_link字典的所有links中,如果是,表示是从链接key访问的页面获取的,key是父链接for key,value in self.refere_extract_link.items():for v in value:extract_url = v[0:v.find("【")]extract_url_text = v[v.find("【")+1: v.find("】")]if response.url == extract_url:referer_url = keyreferer_url_text = extract_url_textreturn referer_url, referer_url_textelse:# 如果refere_extract_link字典的所有links都没有满足条件return,就会执行elsereturn None, None
"""
当迭代对象完成所有迭代后且此时的迭代对象为空时,如果存在else子句则执行else子句,没有则继续执行后续代码;
如果迭代对象因为某种原因(如带有break关键字)提前退出迭代,则else子句不会被执行,程序将会直接跳过else子句继续执行后续代码
"""

备注:逻辑想法记录,方便以后可以直接复用

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

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

相关文章

快快销ShopMatrix 分销商城多端uniapp可编译5端 - 订单金额满多少,一次性订单金额满多少,充值多少升级

“订单金额满多少”或“一次性订单金额满多少”进行升级的商业逻辑。这种策略通常是为了激励用户增加消费额度、提高客单价或者提升用户的活跃度与忠诚度,具有以下好处: 刺激消费增长:商家设置一定的门槛,如一次性订单金额满300元…

C++基础语法和用法

文章目录 1.hello world2.引入namespace(命名空间/域问题)3.输入输出4.缺省参数/默认参数5.函数重载6.引用7.内联函数8.auto关键字&#xff0c;基于范围的for循环&#xff0c;空指针NULL8.1 auto8.2 基于范围的for循环8.3 nullptr 1.hello world #include <iostream> us…

世界经济论坛发布《2024年全球风险报告》和《2024年全球网络安全展望》:网络攻击是2024世界5大风险之一,网络安全经济增速是全球经济的四倍

在近日举行的世界经济论坛 (WEF)上&#xff0c;发布了《2024 年全球风险》报告和《2024年全球网络安全展望》两份重磅报告&#xff0c;分别揭示了全球经济今年和未来几年可能面临的一些关键风险和问题&#xff0c;以及网络安全与全球经济之间的逻辑关系。 2024年全球风险报告 今…

SQL数据库的创建操作

1.如何才能创建一个库、表 CREATE DATABASE 数据库: SHOW databases&#xff1b; USE 数据库; DROP DATABASE 数据库&#xff1b; /*数据表操作/ CREATE TABLE teacher( id int (4) not null primary key auto_increment, name char(20)not null, sex char(10) notnul…

ES6笔记-symbol

ES6 symbol 是什么 ES5的对象属性名是字符串&#xff0c;这容易造成属性名的冲突。symbol是一种机制&#xff0c;保证每个属性的名字都是独一无二的。这样就从根本上防止属性名冲突。 它是一种原始数据类型Symbol,表示独一无二的值。它属于javaScript语言的原生数据类型之一。…

CloudPanel RCE漏洞复现(CVE-2023-35885)

0x01 产品简介 CloudPanel 是一个基于 Web 的控制面板或管理界面,旨在简化云托管环境的管理。它提供了一个集中式平台,用于管理云基础架构的各个方面,包括虚拟机 (VM)、存储、网络和应用程序。 0x02 漏洞概述 由于2.3.1 之前的 CloudPanel 具有不安全的文件管理器 cook…

MyBatis第四课动态SQL

目录 引言&#xff1a; 一、动态SQL书写方式 二、会帮我们处理多余的字符 方法2:使用where也可以进行消除and&#xff0c;但是出现的问题 三、标签 四、foreach(循环操作) ​编辑 Mybatis传递List集合报错 Available parameters are [collection, list] 和 引言&…

Apache Spark中的广播变量分发机制

Apache Spark中的广播变量提供了一种机制&#xff0c;允许用户在集群中共享只读变量&#xff0c;并且每个任务都可以访问这个变量&#xff0c;而不需要在每次任务之间重新发送该变量。这种机制特别适用于在所有节点上都需要访问同一份只读数据集的情况&#xff0c;因为它可以显…

Linux: make/Makefile 相关的知识

背景&#xff1a; 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的 规则来指定&#xff0c;哪些文件需要先编译&#xff0c…

关于小程序吞噬margin-rightBug

关于小程序吞噬margin-right的Bug 今天在写小程序的时候发现我在flex布局的时候我的margin-right不生效 经过测试只能使用display:inline-block; 配合 white-space: nowrap;来实现flex布局同时也解决了不显示右边距的问题 复盘:在小程序中有一个横向滚动的 需求 滚动的屏幕的…

良心推荐!五个超好用的Vue3工具

vue3-dnd 是用来做drag and drop的&#xff0c;也就是拖放&#xff0c;很多人多 Vue 的拖放库已经断代了&#xff0c;其实 Vue3 也有拖放库的&#xff0c;那就是 vue3-dnd。 v-wave 这可库可以通过自定义指令的形式&#xff0c;让目标点击节点具备波纹的效果&#xff0c;如下…

React 18版本配置rem 和 vw

React 18版本配置rem 和 vw 经过无数次的实验最终发现兼容性比较好的方案是配置webpack.config.js 第一步: npm install lib-flexible postcss-pxtorem yarn add lib-flexible postcss-pxtorem第二步: 接下来直接解包-- yarn eject npm run eject第三步: 这一步也是最关键…

mysql的varchar长度到底能插多少字符?

在用navicat迁移表结构&#xff0c;从oracle到MySQL时&#xff0c;注意如下坑&#xff1a; 1、如果varchar2(256)以上&#xff0c;则在mysql会自动用text取代&#xff0c;需要考虑手工修改字段类型为varchar(256) ALTER TABLE DES_LOGIC_RESOURCE MODIFY REMARK VARCHAR(4000);…

MySQL两个表的亲密接触-连接查询的原理

MySQL对于被驱动表的关联字段没索引的关联查询&#xff0c;一般都会使用 BNL 算法。如果有索引一般选择 NLJ 算法&#xff0c;有 索引的情况下 NLJ 算法比 BNL算法性能更高。 关系型数据库还有一个重要的概念&#xff1a;Join&#xff08;连接&#xff09;。使用Join有好处&…

学会使用ubuntu——ubuntu22.04使用WebCatlog

Ubuntu22.04使用WebCatlog WebCatlog是适用于Gnu / Linux&#xff0c;Windows或Mac OS X系统的桌面程序。 引擎基于铬&#xff0c;它用于在我们的桌面上处理Web服务。简单点就是把网页单独一个窗口出来显示&#xff0c;当一个app用。本文就是利用WebCatlog安装后的notion编写的…

如何学习计算机视觉

学习计算机视觉可以通过以下步骤进行&#xff1a; 了解基本概念和原理&#xff1a;首先&#xff0c;你可以学习计算机视觉的基本概念和原理&#xff0c;包括图像处理、特征提取、目标检测、物体识别等。这些基础知识将帮助你理解计算机视觉的工作原理。 学习算法和技术&#x…

C语言-算法-快速幂

【模板】快速幂 题目描述 给你三个整数 a , b , p a,b,p a,b,p&#xff0c;求 a b m o d p a^b \bmod p abmodp。 输入格式 输入只有一行三个整数&#xff0c;分别代表 a , b , p a,b,p a,b,p。 输出格式 输出一行一个字符串 a^b mod ps&#xff0c;其中 a , b , p a…

第九篇 华为云Iot SDK的简单应用

第九篇 华为云Iot SDK的简单应用 一、华为云Iot SDK API的简单使用 1.初始化SDK 2.绑定连接配置信息 3.连接服务器 4.上报属性 5.接收命令 二、实现智能家居灯光状态上报 &#x1f516;以下是上报数据到华为云Iot的代码片段&#xff0c;配合串口控制灯光&#xff0c;改变灯…

Qt —— 自定义飞机仪表控件(附源码)

示例效果 部署环境 本人亲测版本Vs2017+Qt5.12.4,其他版本应该也可使用。 源码1 qfi_ADI::qfi_ADI( QWidget *parent ) :QGraphicsView ( parent ),m_scene ( nullptr )

C++ STL之list的使用及模拟实现

文章目录 1. 介绍2. list类的使用2.1 list类对象的构造函数2.2 list类对象的容量操作2.3 list类对象的修改操作2.4 list类对象的访问及遍历操作 3. list类的模拟实现 1. 介绍 英文解释&#xff1a; 也就是说&#xff1a; list是可以在常数范围内在任意位置进行插入和删除的序列…