如何使用scrapely提取项目列表?

时间:2016-05-31 20:58:27

标签: python data-extraction scrapely

我正在使用scrapely从某些HTML中提取数据,但我在提取项目列表时遇到了困难。

scrapely github project只描述了一个简单的例子:

from scrapely import Scraper
s = Scraper()

s.train(url, data)
s.scrape(another_url)

例如,如果您尝试按照描述提取数据,这很好:

  

用法(API)

     

Scrapely有一个强大的API,包括可以在外部编辑的模板格式,您可以使用它来构建非常强大的刮刀。

该部分后面是最简单的用法的快速示例,您可以在Python shell中运行。

但是,如果您找到类似

的内容,我不确定如何提取数据
Ingredientes

- 50 gr de hojas de albahaca
- 4 cucharadas (60 ml) de piñones
- 2 - 4 dientes de ajo
- 120 ml (1/2 vaso) de aceite de oliva virgen extra
- 115 gr de queso parmesano recién rallado
- 25 gr de queso pecorino recién rallado ( o queso de leche de oveja curado)

我知道我无法通过使用xpath或css选择器来提取它,但我更感兴趣的是使用可以为类似页面提取数据的解析器。

2 个答案:

答案 0 :(得分:5)

Scrapely 可以训练以提取项目列表。诀窍是在训练时传递列表的第一个和最后一个项目作为Python列表。这里有一个受问题启发的例子:(培训:来自url1的10项成分列表,测试:来自url2的7项目列表。)

from scrapely import Scraper

s = Scraper()

url1 = 'http://www.sabormediterraneo.com/recetas/postres/leche_frita.htm'
data = {'ingreds': ['medio litro de leche',   # first and last items
  u'canela y az\xfacar para espolvorear']}
s.train(url1, data)

url2 = 'http://www.sabormediterraneo.com/recetas/cordero_horno.htm'
print s.scrape(url2)

这里输出:

[{u'ingreds': [
  u' 2 piernas o dos paletillas de cordero lechal o recental ',
  u'3 dientes de ajo',
  u'una copita de vino tinto / o / blanco',
  u'una copita de agua',
  u'media copita de aceite de oliva',
  u'or\xe9gano, perejil',
  u'sal, pimienta negra y aceite de oliva']}]

关于问题成分列表(http://www.sabormediterraneo.com/cocina/salsas6.htm)的培训没有直接推广到" recetas"页面。一种解决方案是训练几个刮刀,然后检查哪一个在给定页面上工作。 (在几页上训练一个刮刀在我的快速测试中没有提供一般解决方案。)

答案 1 :(得分:3)

Scrapely可以从结构列表中提取项目列表(例如<ul><ol>) - 请参阅the other answer。但是,因为它使用HTML /文档片段提取内容,所以它无法提取包含在单个标记中的文本格式数据而没有分隔标记(<li></li>),这似乎是您在此处尝试做的

但是,如果您能够整体选择成分块,则可以轻松地对您收到的数据进行后处理以获得所需的输出。例如,在您的示例中,.split('\n')[3:-2]将为您提供以下列表中的成分:

['- 50 gr de hojas de albahaca',
 '- 4 cucharadas (60 ml) de piñones',
 '- 2 - 4 dientes de ajo',
 '- 120 ml (1/2 vaso) de aceite de oliva virgen extra',
 '- 115 gr de queso parmesano recién rallado',
 '- 25 gr de queso pecorino recién rallado ( o queso de leche de oveja curado)']

如果您想定期执行此操作(或需要将后处理添加到多个字段),您可以按如下方式对Scraper类进行子类化以添加自定义方法:

class PostprocessScraper(Scraper):

    def scrape_page_postprocess(self, page, processors=None):
        if processors == None:
            processors = {}

        result = self.scrape_page(page)
        for r in result:
            for field, items in r.items():
                if field in processors:
                    fn = processors[field]
                    r[field] = [fn(i) for i in items]

        return result

这个新方法scrape_page_postprocess接受后处理程序字典,以运行按字段键入的返回数据。例如:

processors = {'ingredients': lambda s: s.split('\n')[3:-2]}
scrape_page_postprocess(page, processors)