我正在使用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选择器来提取它,但我更感兴趣的是使用可以为类似页面提取数据的解析器。
答案 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)