首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我得到一个空的输出,为我的项目刮刮?

为什么我得到一个空的输出,为我的项目刮刮?
EN

Stack Overflow用户
提问于 2014-02-26 22:04:08
回答 1查看 4K关注 0票数 0

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

我的items.py代码如下:

代码语言:javascript
复制
class CinemaItem(Item):
    url = Field()
    name = Field()
    pass

我的cinema_spider.py如下:

代码语言:javascript
复制
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

当我运行以下命令时:

代码语言:javascript
复制
scrapy crawl cinema -o scraped_data.json -t json

输出文件具有这样的内容:

代码语言:javascript
复制
[{"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中的输出如下:

代码语言:javascript
复制
[u'\u0631\u06cc\u062d\u0627\u0646\u0647 \u0628\u0627\u0642\u0631\u06cc \u0628\u0627\u06cc\u06af\u06cc']

我将按以下方式更改蜘蛛代码,以更改编码项:

代码语言:javascript
复制
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')

但却犯了这样一个错误:

代码语言:javascript
复制
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":

代码语言:javascript
复制
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()

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

我读到了几乎所有关于这个问题的堆积如山的文章,但无法解决这个问题。有什么问题吗?

编辑:

HTML的一些片段:

代码语言:javascript
复制
<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>之间的文本

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-26 22:26:58

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

hxs.select(...).extract()将为您提供一个空数组,当您试图更改编码时,您将调用抛出IndexErrorhxs.select(...).extract()[0]

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

而且,您的XPath非常容易易碎,因为它使用绝对位置。这意味着你道路上任何地方的任何改变都会破坏整个过程。通常,最好尝试并依赖于is或唯一的特性(//td[id="foobar"])。

您能提供您要解析的HTML的相关片段吗?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22054397

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档