我認爲我的問題是由一些對某些scrapy
概念的誤解造成的。所以我會很感激,如果有人能夠向我解釋這一點。ItemLoader爲什麼從一個元素創建一個列表
讓我們想象一下,我有以下蜘蛛:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.loader import ItemLoader
from reddit.items import RedditItem
from scrapy.loader.processors import TakeFirst
class RedditspiderSpider(scrapy.Spider):
name = "redditspider"
allowed_domains = ["wwww.reddit.com"]
start_urls = [
'https://www.reddit.com/r/starcraft/comments/5t8v7i/community_feedback_update_widow_mines_carriers/?st=iz7ba37h&sh=b7e9bd35']
def parse(self, response):
l = ItemLoader(item=RedditItem(), response=response)
comments = response.xpath(
'//div[contains(@class,"usertext-body may-blank-within md-container ")]/div')
comments = comments[1:]
for comment_it in comments:
comment = comment_it.extract()
l.add_value('comment', comment)
yield l.load_item()
凡RedditItem
通過以下方式定義:
from scrapy.item import Item, Field
from w3lib.html import remove_tags
from scrapy.loader.processors import TakeFirst
def _remove_tags(input):
return input
class RedditItem(Item):
comment = Field(input_processor=_remove_tags, output_processor=TakeFirst())
所以一切都很簡單明瞭。現在,我的問題。在第一個代碼示例l
加載程序有一個字段comments
。據我所知,當我做l.add_value('comment', comment)
,這個字段的輸入處理器被觸發。 這是正確的嗎?
據我所知,這是正確的。在l.add_value('comment', comment)
comment
是一個字符串,而不是一個列表。但是,當我在_remove_tags
中設置斷點時,我發現input
實際上是長度爲1的列表。所以我的主要問題是爲什麼會發生?爲什麼我傳遞一個字符串並在那裏看到一個列表?
我看着scrapy源代碼,發現這是_add_value
(線90):value = arg_to_iter(value)
。這讓事情變得非常清楚,這似乎是我看到長度爲1的列表的原因。
這條線背後的設計推理是什麼?這是因爲在scrapy
我可以從不同的xpath/css請求填充項目中的相同字段?如果是這樣,那對我來說很有意義。那麼問題是:我該如何解決這個問題?我只是在輸入處理器中應用map(_remove_tags, input)
?這會是一個推薦的解決方案嗎?或者我錯了?
感謝
你確定'comment = comment_it.extract()'是一個字符串嗎? – eLRuLL
@eLRuLL是的。在add_value類型(註釋)---> Out [2]:unicode附近設置一個斷點。似乎是Unicode字符串 –