我已经编写了一个脚本来解析craigslist中某些项目的名称和价格。我的刮刀中定义的xpath
是工作的。问题是,当我尝试以通常方式刮取项目然后应用try/except
块时,当某个价格的值为none时,我可以避免IndexError
。我甚至尝试使用自定义功能使其工作并获得成功。
但是,在下面的代码段中,我想应用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)
答案 0 :(得分:4)
首先,如果路径存在,则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
,则会在attibutes表中获得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