Scrapy:如何从多个值中找到最高/最低值?

时间:2017-07-27 12:22:03

标签: python scrapy

我正在尝试使用Scrapy / Python编写一个爬虫程序,它从页面中读取一些值。

然后我想让这个抓取工具在单独的字段中存储最高和最低值。

到目前为止,我能够从页面中读取值(请参阅下面的代码),但我不确定如何计算最低值和最高值并存储在单独的字段中?

例如,假设抓取工具读取页面并返回这些值

  • t1-score = 75.25
  • t2-score = 85.04
  • t3-score =''(缺少值)
  • t4-score = 90.67
  • t5-score = 50.00

所以我想填充......

  • 'highestscore':90.67
  • 'lowestscore':50.00

我该怎么做?我需要使用数组吗?将所有值放在数组中,然后选择最高/最低?

非常感谢任何帮助。

到目前为止,这是我的代码.... 我正在存储-1,以防丢失值。

 class MySpider(BaseSpider):
            name = "courses"
            start_urls = ['http://www.example.com/courses-listing']
            allowed_domains = ["example.com"]
            def parse(self, response):
             hxs = Selector(response)
             for courses in response.xpath("//meta"):
             {
             d = {
                 'courset1score': float(courses.xpath('//meta[@name="t1-score"]/@content').extract_first('').strip() or -1),
                 'courset2score': float(courses.xpath('//meta[@name="t2-score"]/@content').extract_first('').strip() or -1),
                 'courset3score': float(courses.xpath('//meta[@name="t3-score"]/@content').extract_first('').strip() or -1),
                 'courset4score': float(courses.xpath('//meta[@name="t4-score"]/@content').extract_first('').strip() or -1),
                 'courset5score': float(courses.xpath('//meta[@name="t5-score"]/@content').extract_first('').strip() or -1),
                 }
             d['highestscore'] = max(d.values())
             d['lowestscore'] = min(d.values())
             'pagetitle': courses.xpath('//meta[@name="pagetitle"]/@content').extract_first(),
             'pageurl': courses.xpath('//meta[@name="pageurl"]/@content').extract_first(),
             }

             for url in hxs.xpath('//ul[@class="scrapy"]/li/a/@href').extract():
              // yield Request(response.urljoin(url), callback=self.parse)
              yield d

2 个答案:

答案 0 :(得分:0)

在yield语句之前构建字典。这将允许您引用字典中已有的值。

for courses in response.xpath("//meta"):
    d = {'courset1score': float(courses.xpath('//meta[@name="t1-score"]/@content').extract_first('').strip() or -1),
         'courset2score': float(courses.xpath('//meta[@name="t2-score"]/@content').extract_first('').strip() or -1),
         'courset3score': float(courses.xpath('//meta[@name="t3-score"]/@content').extract_first('').strip() or -1),
         'courset4score': float(courses.xpath('//meta[@name="t4-score"]/@content').extract_first('').strip() or -1),
         'courset5score': float(courses.xpath('//meta[@name="t5-score"]/@content').extract_first('').strip() or -1),
           }

    d['highestscore'] = max(d.values())
    d['lowestscore'] = min(d.values())
    yield d

答案 1 :(得分:0)

假设我们有这个html文档示例:

body = """
<meta name="t1-score" content="10"></meta>
<meta name="t2-score" content="20"></meta>
<meta name="t3-score" content="5"></meta>
<meta name="t4-score" content="8"></meta>
"""
sel = Selector(text=body)

我们可以提取分数,转换为数字对象并使用内置的minmax函数。

# you can use this xpath to select any score 
scores = sel.xpath("//meta[re:test(@name, 't\d-score')]/@content").extract()
# ['10', '20', '5', '8']
scores = [float(score) for score in scores]
# [10.0, 20.0, 5.0, 8.0]
min(scores)
# 5.0
max(scores)
# 20.0

组合输出:

item = dict()
item['max_score'] = max(scores)
item['min_score'] = min(scores)
for i, score in enumerate(scores):
    item['score{}'.format(i)] = score