在我的刮刀中使用 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函数时遇到的问题及解决方法