如何使用Scrapy从页面的不同部分收集数据?

时间:2017-08-01 15:05:14

标签: python xpath scrapy

我有兴趣从this等网页中选择一些数据。我写了以下脚本来做到这一点。问题是我选择了4个部分(坩埚,泰坦,猎人,术士),但不同页面的数据位置并不相同。我不确定我选择不同部分的方法是否合适。

 def parse_country(self, response):

    hxs = scrapy.Selector(response)

    crucibleSummary = hxs.xpath('//*[@id="site-body"]/div[5]/div/div/div[1]/div[4]/div[2]').xpath('.//text()').extract()
    crucibleSummaryData = [e.replace(',', '').replace('%', '').replace('\n', '').replace('Top', '').
                           replace('#', '').replace('\r', '').replace('\n', '').strip()
                           for e in crucibleSummary]
    crucibleSummaryData = filter(None, crucibleSummaryData)

    titan = hxs.xpath('//*[@id="site-body"]/div[5]/div/div/div[2]/div[3]/div[2]').xpath('.//text()').extract()
    titanData = [e.replace(',', '').replace('%', '').replace('\n', '').replace('Top', '').replace('#', '').
                      replace('\r', '').replace('\n', '').strip() for e in titan]
    titanData = filter(None, titanData)

    warlock = hxs.xpath('//*[@id="site-body"]/div[5]/div/div/div[2]/div[3]/div[3]').xpath('.//text()').extract()
    warlockData = [e.replace(',', '').replace('%', '').replace('\n', '').replace('Top', '').replace('#', '').
                      replace('\r', '').replace('\n', '').strip() for e in warlock]
    warlockData = filter(None, warlockData)

    hunter = hxs.xpath('//*[@id="site-body"]/div[5]/div/div/div[2]/div[3]/div[1]').xpath('.//text()').extract()
    hunterData = [e.replace(',', '').replace('%', '').replace('\n', '').replace('Top', '').replace('#', '').
                      replace('\r', '').replace('\n', '').strip() for e in hunter]
    hunterData = filter(None, hunterData)


    item = DestinytrackerProfilesItem()
    data = crucibleSummaryData
    item['DTRscore'] = [float(data[1]),  float(data[2])]
    ....

1 个答案:

答案 0 :(得分:1)

您当前的XPath表达式非常脆弱且无法读取。

如果不依赖于父div元素及其位置的相对位置,我们会使用块标题 - 如果是Crucible,它可能是:

//h2[. = 'Crucible Summary']/following::div[@class='stats-stat-list']

对于术士和其他角色,您可以查找strong元素文本以包含子字符串:

//div[@class = "character-details" and contains(.//strong, "Warlock")]