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

How to extract a list of items using scrapely?

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

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

from scrapely import Scraper
s = Scraper()

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

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

Usage (API)

Scrapely has a powerful API, including a template format that can be edited externally, that you can use to build very capable scrapers.

该部分后面是最简单用法的快速示例,您可以在 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 选择器来提取它,但我更感兴趣的是使用可以为类似页面提取数据的解析器。

Scrapely 可以从结构列表中提取项目列表(例如 <ul><ol>)——参见 。但是,因为它使用 HTML/document 片段提取内容,所以它无法提取包含在没有定界标签(<li></li>)的单个标签中的文本格式数据,这似乎是您想要的在这里做。

但是,如果您能够 select 将成分块作为一个整体,则可以轻松地 post 处理您收到的数据以获得所需的输出。例如,在您的示例中 .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)']

如果您想定期执行此操作(或需要向多个字段添加 post 处理),您可以将 class Scraper class 子class 如下添加自定义方法:

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 接受 post 处理器的字典,以 运行 跨按字段键入的返回数据。例如:

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

Scrapely 可以 训练以提取项目列表。诀窍是在训练时将要提取的列表的第一项和最后一项作为 Python 列表传递。这是一个受问题启发的示例:(训练:来自 url1, test: 7-item list from url2 的 10 项成分列表。)

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" 页面。一种解决方案是训练多个爬虫,然后检查哪一个在给定页面上有效。 (在几个页面上训练一个 scraper在我的快速测试中没有给出通用的解决方案。)