我试图从具有以下结构的网站抓取数据。我想在每个<li id="entry">
中提取信息,但这两个条目还应从<li id="category"> / <h2>
<ul class="html-winners">
<li id="category">
<h2>Redaktionell Print - Dagstidning</h2>
<ul>
<li id="entry">
<div class="entry-info">
<div class="block">
<img src="bilder/tumme10/4.jpg" width="110" height="147">
<span class="gold">Guld: Svenska Dagbladet</span><br>
<strong><strong>Designer:</strong></strong> Anna W Thurfjell och SvD:s medarbetare<br>
<strong><strong>Motivering:</strong></strong> "Konsekvent design som är lätt igenkänningsbar. Små förändringar förnyar ständigt och blldmotiven utnyttjas föredömligt."
</div>
</div>
</li>
<li id="entry">
<div class="entry-info">
<div class="block"><img src="bilder/tumme10/3.jpg" width="110" height="147">
<span class="silver">Silver: K2 - Kristianstadsbladet</span>
</div>
</div>
</li>
</ul>
</li>
我使用scrapy并使用以下代码:
start_urls = [
"http://www.designpriset.se/vinnare.php?year=2010"
]
rules = (
Rule(LinkExtractor(allow = "http://www.designpriset.se/", restrict_xpaths=('//*[@class="html-winners"]')), callback='parse_item'),
)
def parse(self, response):
for sel in response.xpath('//*[@class="entry-info"]'):
item = ByrauItem()
annons_list = sel.xpath('//span[@class="gold"]/text()|//span[@class="silver"]/text()').extract()
byrau_list = sel.xpath('//div/text()').extract()
kategori_list = sel.xpath('/preceding::h2/text()').extract()
for x in range(0,len(annons_list)):
item['Annonsrubrik'] = annons_list[x]
item['Byrau'] = byrau_list[x]
item['Kategori'] = kategori_list[x]
yield item
annons_list和byrau_list工作正常,他们使用xpath从起点//*[@class="entry-info"]
开始沿着层次结构前进。但是kategori_list给了我&#34; IndexError:列表索引超出范围&#34;。我是以错误的方式写出xpath之前的xpath吗?
答案 0 :(得分:2)
正如评论中@kjhughes所述,您需要在.
或/
之前添加//
,以使您的XPath表达式相对于当前上下文元素。否则,表达式将被视为相对于根文档。这就是为什么表达式/preceding::h2/text()
没有返回任何内容。
对于/
,您也可以将其从XPath表达式的开头删除,作为相对于当前上下文元素的替代方法:
kategori_list = sel.xpath('preceding::h2/text()').extract()
只需注释,preceding::h2
将返回位于h2
之前的所有<div class="entry-info">
元素。根据发布的HTML,我认为以下XPath表达式更容易返回不需要的h2
元素(误报):
query = 'parent::li/parent::ul/preceding-sibling::h2/text()'
kategori_list = sel.xpath(query).extract()