代码之家  ›  专栏  ›  技术社区  ›  Toleo

在一个循环中刮掉多个页面给出了第三级的重复结果。

  •  0
  • Toleo  · 技术社区  · 7 年前

    在下面的HTML模板中:


    1级 (模板1)

    <ul>
        <li>
            <a href="template_2.html">Template 2 (Level 2)</a>
        </li>
    </ul>

    二级 (模板二)

    <ul>
        <li>
            <a href="template_3.html">Template 3 (Level 3)</a>
        </li>
        <li>
            <a href="template_4.html">Template 4 (Level 3)</a>
        </li>
    </ul>

    三级 (模板3和模板4)

    <h1>Template 3 Text</h1>

    <h1>Template 4 Text</h1>

    我要做的是进入 1级 HTML 翻页,然后拉 文本 每一个 a 元素,然后输入它来拉动每个 h1 要素 文本 使用以下三脚架:

    # -*- coding: utf-8 -*-
    import scrapy
    
    
    class LESpider(scrapy.Spider):
        name = 'Loop Error'
        start_urls = ['template_1.html']
    
        def parse(self, response):
            data = {
                'temp_text': None,
                'text': None
            }
    
            yield scrapy.Request(url=response.css('a::attr(href)').extract_first(), callback=self.parse_lv2, dont_filter=True, meta={"data": data})
    
        def parse_lv2(self, response):
            for a in response.css('a'):
                data = response.meta.get('data')
    
                data['temp_text'] = a.css('a::text').extract_first()
    
                yield scrapy.Request(url=a.css('a::attr(href)').extract_first(), callback=self.parse_lv3, dont_filter=True, meta={"data": data})
    
    
        def parse_lv3(self, response):
            data = response.meta.get('data')
    
            data['text'] = response.css('h1::text').extract_first()
    
            yield data
    

    我的问题是,首先,我期望的结果是

    [
      {"temp_text": "Template 3 (Level 3)", "text": 'Template 3 Text'},
      {"temp_text": "Template 4 (Level 3)", "text": 'Template 4 Text'}
    ]
    

    但我得到的结果是:

    [
      {"temp_text": "Template 4 (Level 3)", "text": "Template 3 Text"},
      {"temp_text": "Template 4 (Level 3)", "text": "Template 4 Text"}
    ]
    

    我得到的地方 temp_text 复制的最后一个值 元素 二级

    我想问题是我把 yield data 所以我把它放在 分析级别2 yield 这样地

    yield scrapy.Request(url=a.css('a::attr(href)').extract_first(), callback=self.parse_lv3, dont_filter=True, meta={"data": data})
    
    yield data
    

    但没有从 分析级别3 我是说,

    试图检查哪个部分有问题,所以我删除了 分析级别3 以及 yield scrapy.Request(url=a.css('a::attr(href)').extract_first(), callback=self.parse_lv3, dont_filter=True, meta={"data": data}) 分析级别2 我是说,

    替换为 产量数据 我是说,

    问题解决了 分析级别3 数据)。

    所以我确定问题不是在循环中就是 分析级别3 产量 ,但不知道如何解决。

    1 回复  |  直到 7 年前
        1
  •  1
  •   mxmn    7 年前

    问题可能是你只定义 data 曾经 parse 所以每一个循环 parse_lv2 将共享同一条指令 数据 每一个循环 parse_lv3 将共享 数据 这就是为什么在最后你得到了 分析级别2 在里面 data['temp_text'] .

    你最好初始化 数据 在循环中 分析级别2 像那样

    def parse(self, response):
        yield scrapy.Request(url=response.css('a::attr(href)').extract_first(), callback=self.parse_lv2, dont_filter=True)
    
    
    def parse_lv2(self, response):
        for a in response.css('a'):
            data = dict()
            data['temp_text'] = a.css('a::text').extract_first()
            yield scrapy.Request(url=a.css('a::attr(href)').extract_first(), callback=self.parse_lv3, dont_filter=True, meta={"data": data})
    
    推荐文章