在我的刮刀中使用 lambda 函数时遇到问题

Posted

技术标签:

【中文标题】在我的刮刀中使用 lambda 函数时遇到问题【英文标题】:Trouble using lambda function within my scraper 【发布时间】:2018-08-24 08:00:11 【问题描述】:

我编写了一个脚本来解析 craigslist 中某些商品的名称和价格。我在刮板中定义的xpath 正在工作。问题是当我尝试以通常的方式刮擦物品然后应用try/except 块时,当某个价格的价值为零时,我可以避免IndexError。我什至尝试使用自定义功能使其工作并获得成功。

但是,在下面的 sn-p 中,我想应用 lambda 函数来排除 IndexError 错误。我试过了,但没有成功。

顺便说一句,当我运行代码时,它既没有获取任何东西,也没有抛出任何错误。

import requests
from lxml.html import fromstring

page = requests.get('http://bangalore.craigslist.co.in/search/rea?s=120').text
tree = fromstring(page)

# I wish to fix this function to make a go
get_val = lambda item,path:item.text if item.xpath(path) else ""

for item in tree.xpath('//li[@class="result-row"]'):
    link = get_val(item,'.//a[contains(@class,"hdrlnk")]')
    price = get_val(item,'.//span[@class="result-price"]')
    print(link,price)

【问题讨论】:

不要使用lambda 表达式来定义命名函数;只需使用def 声明即可。 【参考方案1】:

首先,如果路径存在,您的 lambda 函数 get_val 返回项目的文本,而不是搜索节点的文本。这可能不是你想要的。如果想返回匹配路径的(第一个)元素的文本内容,你应该写:

get_val = lambda item, path: item.xpath(path)[0].text if item.xpath(path) else ""

请注意xpath 返回一个列表。我在这里假设您在该列表中只有一个元素。

输出是这样的:

...
Residential Plot @ Sarjapur Check Post ₨1000
Prestige dolce vita apartments in whitefield, Bangalore 
Brigade Golden Triangle, ₨12500000
Nikoo Homes, ₨6900000

但我认为您需要的是链接,而不是文本。如果是这种情况,请阅读下文。

好的,如何获取链接?当你有一个锚a 时,你会在属性表中获得它的href(链接):a.attrib["href"]

据我了解,在价格的情况下,您需要文本,但在锚点的情况下,您需要一个特定属性的值,href。这是 lambdas 的真正用途。像这样重写你的函数:

def get_val(item, path, l):
    return l(item.xpath(path)[0]) if item.xpath(path) else ""

参数l是应用于节点的函数。 l 可以返回节点的文本,或者锚点的href:

link = get_val(item,'.//a[contains(@class,"hdrlnk")]', lambda n: n.attrib["href"])
price = get_val(item,'.//span[@class="result-price"]', lambda n: n.text)

现在的输出是:

...
https://bangalore.craigslist.co.in/reb/d/residential-plot-sarjapur/6522786441.html ₨1000
https://bangalore.craigslist.co.in/reb/d/prestige-dolce-vita/6522754197.html 
https://bangalore.craigslist.co.in/reb/d/brigade-golden-triangle/6522687904.html ₨12500000
https://bangalore.craigslist.co.in/reb/d/nikoo-homes/6522687772.html ₨6900000

【讨论】:

以上是关于在我的刮刀中使用 lambda 函数时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

从 NodeJS AWS Lambda 函数查询 MySQL 数据库

使用 API Gateway 处理 AWS Lambda 函数中的错误

Java+Spark 实现 flatMapToPair 的lambda函数时遇到的问题及解决方法

使用代理通过 AWS API Gateway 的 Lambda 错误

Tkinter lambda 函数

超出范围后,在Lambda中设置共享指针