我是蟒蛇和刮痕的新手。我将抓取一些链接的页面来获取我想要的数据,但是当我生成输出时,我想要的项是空的。
我的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()但是,结果输出文件与空名称项相同。
我读到了几乎所有关于这个问题的堆积如山的文章,但无法解决这个问题。有什么问题吗?
编辑:
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>之间的文本
发布于 2014-02-26 22:26:58
问题很可能是您的XPath与您想要的数据不匹配。
hxs.select(...).extract()将为您提供一个空数组,当您试图更改编码时,您将调用抛出IndexError的hxs.select(...).extract()[0]。
你是怎么找到那个XPath的?你在你的蜘蛛里面测试过吗?注意,浏览器和scrapy中显示的HTML可能是不同的,通常是因为scrapy不执行javascript。作为一般规则,您应该始终检查response.body是否符合您的期望。
而且,您的XPath非常容易易碎,因为它使用绝对位置。这意味着你道路上任何地方的任何改变都会破坏整个过程。通常,最好尝试并依赖于is或唯一的特性(//td[id="foobar"])。
您能提供您要解析的HTML的相关片段吗?
https://stackoverflow.com/questions/22054397
复制相似问题