当前位置: 首页 > article >正文

Scrapy之一个item包含多级页面的处理方案

目标

        在实际开发过程中,我们所需要的数据往往需要通过多个页面的数据汇总得到,通过列表获取到的数据只有简单的介绍。站在Scrapy框架的角度来看,实际上就是考虑如何处理一个item包含多级页面数据的问题。本文将以获取叶子猪网站的手游排行榜及手游详情为学习案例来解决这个问题。


版本

        Scrapy 2.12.0


实战

第一步:搭建Scrapy框架。略过,如果不会搭建的通过可以看我之前的Scrapy入门文章。

第二步:通过打开目标网页,查看网页代码,我们可以的到手游排行榜的基础信息,这里我们只获取标题。

import scrapy


class SytopSpider(scrapy.Spider):
    name = "sytop"
    allowed_domains = ["sy.yzz.cn"]
    start_urls = ["http://sy.yzz.cn/news/14324-1.shtml"]

    def parse(self, response):
        a_list = response.xpath("//ul[@class='item-pt-list']/li/div[1]/a")
        for a in a_list:
            # 标题
            alt = a.xpath("./img/@alt").get()
            print(alt)

第三步:进入二级页面,获取描述信息。此时日志打印可以看到,单个游戏的信息并没有组合起来。

import scrapy


class SytopSpider(scrapy.Spider):
    name = "sytop"
    allowed_domains = ["sy.yzz.cn"]
    start_urls = ["http://sy.yzz.cn/news/14324-1.shtml"]

    def parse(self, response):
        a_list = response.xpath("//ul[@class='item-pt-list']/li/div[1]/a")
        for a in a_list:
            # 标题
            alt = a.xpath("./img/@alt").get()
            print(alt)
            # 二级页面的url
            info_url = a.xpath("./@href").get()
            print(f'二级页面的url是:{info_url}')
            meta = {
                "alt": alt
            }

            yield scrapy.Request(url=info_url, callback=self.parse_info)

    def parse_info(self, response):
        p_list = response.xpath("//div[@class='content']//p")
        for p in p_list:
            content=p.xpath("string(.)").get()
            print(content)

第四步:组合item数据。scrapy.Request方法中的meta参数很重要,它实现了深度爬取。比如:在爬取多层级页面时,使用 meta 参数传递父页面的信息到子页面。

import scrapy

from yezizhu.items import YezizhuItem


class SytopSpider(scrapy.Spider):
    name = "sytop"
    allowed_domains = ["sy.yzz.cn"]
    start_urls = ["http://sy.yzz.cn/news/14324-1.shtml"]

    def parse(self, response):
        a_list = response.xpath("//ul[@class='item-pt-list']/li/div[1]/a")
        for a in a_list:
            # 标题
            alt = a.xpath("./img/@alt").get()
            # 二级页面的url
            info_url = a.xpath("./@href").get()
            meta = {
                "alt": alt
            }

            yield scrapy.Request(url=info_url, callback=self.parse_info,meta=meta)

    def parse_info(self, response):
        p_list = response.xpath("//div[@class='content']//p")
        print("==============start================")
        alt = response.meta["alt"]
        print(alt)
        content=""
        for p in p_list:
            content=content+"\n"+p.xpath("string(.)").get()
        print(content)

第五步:创建item属性。

class YezizhuItem(scrapy.Item):
    alt = scrapy.Field()
    content = scrapy.Field()

第六步:传递item属性值,并将item对象传递给管道。

import scrapy

from yezizhu.items import YezizhuItem


class SytopSpider(scrapy.Spider):
    name = "sytop"
    allowed_domains = ["sy.yzz.cn"]
    start_urls = ["http://sy.yzz.cn/news/14324-1.shtml"]

    def parse(self, response):
        a_list = response.xpath("//ul[@class='item-pt-list']/li/div[1]/a")
        for a in a_list:
            # 标题
            alt = a.xpath("./img/@alt").get()
            # 二级页面的url
            info_url = a.xpath("./@href").get()
            meta = {
                "alt": alt
            }

            yield scrapy.Request(url=info_url, callback=self.parse_info,meta=meta)

    def parse_info(self, response):
        p_list = response.xpath("//div[@class='content']//p")
        print("==============start================")
        alt = response.meta["alt"]
        print(alt)
        content=""
        for p in p_list:
            content=content+"\n"+p.xpath("string(.)").get()
        print(content)
        top_content=YezizhuItem(alt=alt, content=content)
        yield top_content

第七步:在settings.py文件中开启管道。

ITEM_PIPELINES = {
   "yezizhu.pipelines.YezizhuPipeline": 300,
}

第八步:在管道中设置下载数据并启动项目。

import json

class YezizhuPipeline:
    # 在爬虫文件开始之前就执行的方法
    def open_spider(self, spider):
        self.fp = open("C:\\Users\\Administrator\\Desktop\\test\\a.json", "w", encoding="utf-8")
        self.fp.write("[")

    def process_item(self, item, spider):
        line = json.dumps(dict(item), ensure_ascii=False) + ",\n"
        self.fp.write(line)
        return item

    # 在爬虫文件执行之后再执行的方法
    def close_spider(self, spider):
        # 删除最后一个多余的逗号,并关闭 JSON 数组
        self.fp.seek(self.fp.tell() - 3, 0)
        self.fp.write("\n]")
        self.fp.close()


http://www.kler.cn/a/516761.html

相关文章:

  • Spring中的事务管理器TransactionManager
  • vue3组件传值具体使用
  • 编写子程序
  • Mac 查看 Java SDK 和 Android SDK 的路径
  • [论文阅读] (36)CS22 MPSAutodetect:基于自编码器的恶意Powershell脚本检测模型
  • QT:控件属性及常用控件(3)-----输入类控件(正则表达式)
  • docker运行长期处于activating (start)
  • 【十年java搬砖路】oracle链接失败问题排查
  • 基于ollama,langchain,springboot从零搭建知识库四【设计通用rag系统】
  • 掌握Spring事务隔离级别,提升并发处理能力
  • element-plus 的table section如何实现单选
  • 亚博microros小车-原生ubuntu支持系列:6-整体检测
  • Android SystemUI——快捷面板的创建(十四)
  • 禁止 iOS 系统浏览器双指放大页面
  • blender 安装笔记 linux 2025
  • 56.命令绑定 C#例子 WPF例子
  • (DM)达梦数据库基本操作(持续更新)
  • Springboot使用war启动的配置
  • 知识图谱结合大模型用于聊天分析
  • excel批量提取批注
  • c# 打印字符串
  • 迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-添加内核编译
  • C语言常用知识结构深入学习
  • vue项目的创建
  • GPU算力平台|在GPU算力平台部署MedicalGPT医疗大模型的应用教程
  • MyBatis最佳实践:MyBatis 框架的缓存