在将scrapy爬虫结果插入postgresql时的花括号问题

0 投票
2 回答
545 浏览
提问于 2025-04-30 00:18

在使用 scrapy shell 的时候:

scrapy shell “http://blogs.reuters.com/us/“

我想提取网址的标题:

response.xpath('(//title/text())').extract()

结果是:

[u’Analysis & Opinion | Reuters']

当我运行爬虫时,我在我的 postgresql 数据库中得到以下内容:

{“Analysis & Opinion | Reuters”}

我想要的是:

Analysis & Opinion | Reuters

我该怎么做才能实现这个?另外,这里是我正在使用的管道,如果有帮助的话:

import scrapy
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors import LinkExtractor
from targets.items import TargetsItem

class MySpider(CrawlSpider):
    name = 'reuters'
    allowed_domains = ['blogs.reuters.com']
    start_urls = [
        'http://blogs.reuters.com/us/'
    ]

    rules = (
       Rule(LinkExtractor(allow_domains=('blogs.reuters.com', )), callback='parse_item'),
    )

    def parse_item(self, response):
        item = TargetsItem()
        item['title'] = response.xpath('(//title/text())').extract()
        item['link'] = response.url
        return item
暂无标签

2 个回答

1

[u’Analysis & Opinion | Reuters'] 是一个Python列表的文本表示,这个列表里包含了一个unicode字符串 'Analysis & Opinion | Reuters'。把

item['title'] = response.xpath('(//title/text())').extract()

替换成

item['title'] = response.xpath('(//title/text())').extract()[0]

就可以了(当然前提是 response.xpath('(//title/text())').extract() 返回的列表长度要大于等于1)。

1

最好的选择是使用 项目加载器输入输出处理器

项目加载器提供了一种方便的方式来填充抓取到的项目。虽然你可以用字典的方式直接填充项目,但项目加载器提供了一种更简单的方式来从抓取过程中填充这些项目,它可以自动处理一些常见的任务,比如在分配数据之前先解析原始提取的数据。

特别是 TakeFirst() 处理器。你需要定义你的加载器:

from scrapy.contrib.loader import ItemLoader
from scrapy.contrib.loader.processor import TakeFirst, MapCompose

class TargetLoader(ItemLoader):
    default_output_processor = TakeFirst()

然后使用加载器来加载项目:

def parse_item(self, response):
    l = TargetLoader(TargetsItem(), response)

    l.add_xpath('title', '//title/text()')
    l.add_value('link', response.url)

    return l.load_item()

示例:

$ scrapy shell http://blogs.reuters.com
>>> import scrapy
>>> from scrapy.contrib.loader import ItemLoader
>>> from scrapy.contrib.loader.processor import TakeFirst, MapCompose
>>> class TargetItem(scrapy.Item):
...     title = scrapy.Field()
...     link = scrapy.Field()
... 
>>> class TargetLoader(ItemLoader):
...     default_output_processor = TakeFirst()
... 
>>> l = TargetLoader(TargetItem(), response)
>>> l.add_xpath('title', '//title/text()')
>>> l.add_value('link', response.url)
>>> l.load_item()
{'link': 'http://blogs.reuters.com/us/',
 'title': u'Analysis & Opinion | Reuters'}

撰写回答