我是蟒蛇和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>
答案 0 :(得分:4)
问题很可能是您的XPath与您想要的数据不匹配。
hxs.select(...).extract()
会为您提供一个空数组,当您尝试更改正在调用hxs.select(...).extract()[0]
的编码时会抛出IndexError
。
你是如何找到XPath的?你在蜘蛛里测试了吗?请注意,浏览器和scrapy中显示的 HTML可能不同,通常是因为scrapy不执行javascript。作为一般规则,您应始终检查response.body
是否符合预期。
此外,您的XPath非常容易破解,因为它使用绝对位置。这意味着你路径中任何地方的任何变化都会破坏整个事物。通常最好尝试依赖id或独特特征(//td[id="foobar"]
)。
您能否提供您尝试解析的HTML的相关片段?