在我的以下HTML模板中:
1级(模板_1)
<ul>
<li>
<a href="template_2.html">Template 2 (Level 2)</a>
</li>
</ul>
2级(模板_2)
<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级(Template_3和Template_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"}
]
我在哪里获得了{strong.Level 2
中temp_text
元素的最后一个值的a
重复项
我认为问题出在我放置yield data
的位置,所以我把它放在 parse_lv2 的yield
下面
yield scrapy.Request(url=a.css('a::attr(href)').extract_first(), callback=self.parse_lv3, dont_filter=True, meta={"data": data})
yield data
但是没有从 parse_lv3 ,
获得数据试图检查出问题所在,所以我从 parse_lv2 中删除了 parse_lv3 和yield scrapy.Request(url=a.css('a::attr(href)').extract_first(), callback=self.parse_lv3, dont_filter=True, meta={"data": data})
,
用yield data
代替
问题解决了(没有 parse_lv3 数据),
因此,我确定问题是在循环中还是在 parse_lv3 yield
中,但不知道如何解决。
答案 0 :(得分:1)
问题可能是您只在data
中定义了一次parse
,因此parse_lv2
中的每个循环将共享相同的字典data
,而{{1}中的每个循环}也将共享parse_lv3
,这就是为什么最后在data
中有parse_lv2
的最后一个循环的结果的原因。
最好在data['temp_text']
循环中初始化data
parse_lv2