为什么我的物品在scrapy中得到空输出?

时间:2014-02-26 22:04:08

标签: python scrapy python-unicode

我是蟒蛇和scrapy的新手。我要刮一些链接的页面来获取我想要的数据但是当我生成输出时,我想要的项目是空的。

我的items.py代码如下:

class CinemaItem(Item):
    url = Field()
    name = Field()
    pass

我的cinema_spider.py如下:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import Selector
from scrapy.selector import HtmlXPathSelector
from cinema.items import CinemaItem

class CinemaSpider(CrawlSpider):
    name = "cinema"
    allowed_domains = ["example.com"]
    start_urls = [
        "http://www.example.com/?user=artists"
    ]
    rules = [Rule(SgmlLinkExtractor(allow=['/\?user=profile&detailid=\d+']),'parse_cinema')]

    def parse_cinema(self, response):
        hxs = HtmlXPathSelector(response)
        cinema = CinemaItem()
        cinema['url'] = response.url
        cinema['name'] = hxs.select("//html/body/table/tbody/tr[2]/td/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td/text()").extract()
        return cinema

当我运行以下命令时:

scrapy crawl cinema -o scraped_data.json -t json

输出文件包含以下内容:

[{"url": "http://www.example.com/?detailid=218&user=profile", "name": []},
{"url": "http://www.example.com/?detailid=322&user=profile", "name": []},
{"url": "http://www.example.com/?detailid=219&user=profile", "name": []},
{"url": "http://www.example.com/?detailid=221&user=profile", "name": []}]

如你所见,名称项是空的,虽然事实上,它们有值,我可以在scrapy shell中获取它们时获取它们。但是,由于它们的值是波斯语,可能是unicode格式,因此shell中的输出为:

[u'\u0631\u06cc\u062d\u0627\u0646\u0647 \u0628\u0627\u0642\u0631\u06cc \u0628\u0627\u06cc\u06af\u06cc']

我更改了蜘蛛代码,如下所示更改项目编码:

cinema['name'] = hxs.select("//html/body/table/tbody/tr[2]/td/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td/text()").extract()[0].encode('utf-8')

但是出现了这样的错误:

cinema['name'] = hxs.select("//html/body/table/tbody/tr[2]/td/table/tbody/tr/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr[2]/td/table/tbody/tr/td/text()").extract()[0].encode('utf-8')
exceptions.IndexError: list index out of range

然后,我撤消对我的蜘蛛代码的更改,并根据此post,编写我自己的pipelines.py来更改ensure_ascii的默认值并将其变为“False”:

import json
import codecs

class CinemaPipeline(object):

    def __init__(self):
        self.file = codecs.open('scraped_data_utf8.json', 'wb', encoding='utf-8')

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

    def spider_closed(self, spider):
        self.file.close()

但是,结果输出文件与空名称项相同。

我几乎阅读了有关此问题的stackoverflow中的所有帖子,但无法解决此问题。有什么问题?

编辑:

HTML的一些片段:

<div class="content font-fa" style="margin-top:10px;">
    <div class="content-box">
        <div class="content-text" dir="rtl" style="width:240px;min-height:200px;text-align:center"><img src='../images/others/no-photo.jpg' ></div>
        <div class="content-text" dir="rtl" style="width:450px;float:right;min-height:200px;" >
            <div class="content-row" style="text-align:right;margin-right:0px;">
                <span class="FontsFa">
                    <span align="right">
                        <strong class="font-11 "> نام/نام خانوادگی : </strong>
                    </span>
                    <span class="large-title">
                        <span class="bold font-13" style="color:#900;">ریحانه باقری بایگی
                        </span>
                    </span>
               </span>
            </div>

我想在<span class="bold font-13" style="color:#900;">ریحانه باقری بایگی </span>

之间获取文字

1 个答案:

答案 0 :(得分:4)

问题很可能是您的XPath与您想要的数据不匹配。

hxs.select(...).extract()会为您提供一个空数组,当您尝试更改正在调用hxs.select(...).extract()[0]的编码时会抛出IndexError

你是如何找到XPath的?你在蜘蛛里测试了吗?请注意,浏览器和scrapy中显示的 HTML可能不同,通常是因为scrapy不执行javascript。作为一般规则,您应始终检查response.body是否符合预期。

此外,您的XPath非常容易破解,因为它使用绝对位置。这意味着你路径中任何地方的任何变化都会破坏整个事物。通常最好尝试依赖id或独特特征(//td[id="foobar"])。

您能否提供您尝试解析的HTML的相关片段?