如何使用 CSS 选择器(Scrapy)从包含特定文本的 class 获取 href

How to get href from a class containing a specific text using CSS selector (Scrapy)

我正在使用以下网站:https://inmuebles.mercadolibre.com.mx/venta/,我正在尝试从“Inmueble”部分(红色)的“ver_todos”按钮获取 link .但是,“Tour virtual”和“Publicados hoy”部分(蓝色)在访问网站时可能会或可能不会出现。

如下图所示,classes ui-search-filter-dl 包含上图中菜单中的特定部分;而 ui-search-filter-container classes 包含网站显示的 sub-sections(例如 Inmueble 的 Casas、Departamento 和 Terrenos)。为了从“Inmueble”部分的“ver todos”按钮获取 link,我使用了这行代码:

ver_todos = response.css('div.ui-search-filter-dl')[2].css('a.ui-search-modal__link').attrib['href']

但是由于“Tour virtual”和“Publicados hoy”并不总是在页面中,我不能确定索引 2 处的 ui-search-filter-dl 始终是与“ver todos”按钮对应的索引。

我试图通过使用这行代码从“ver todos”获取 link:

response.css(''':contains("Inmueble") ~ .ui-search-filter-dt-title
                            .ui-search-modal__link::attr(href)''').extract()

基本上,我试图从包含标题“Inmueble”的 ui-search-filter-dt-title class 中获取 href。不幸的是,输出是一个空列表。我想使用 css 和正则表达式从“ver todos”中找到 link,但我遇到了麻烦。我该如何实现?

一个简单的方法是获取所有 link <a>,然后检查它们的任何文本是否匹配 ver todos.

import requests
from bs4 import BeautifulSoup

link = "https://inmuebles.mercadolibre.com.mx/venta/"

def main():
  res = requests.get(link)
  if res.status_code == 200:
    soup = BeautifulSoup(res.text, "html.parser")
    links = [a["href"] for a in soup.select("a") if a.text.strip().lower() == "ver todos"]
    print(links)


if __name__ == "__main__":
  main()

我认为 xpath 在大多数情况下更容易 select 目标元素:

代码:

xpath = "//div[contains(text(), 'Inmueble')]/following-sibling::ul//a[contains(@class,'ui-search-modal__link')]/@href"
url = response.xpath(xpath).extract()[0]

其实我创建scrapy项目并不是为了检查你的代码。或者,我实现了以下代码:

from lxml import html
import requests

res = requests.get( "https://inmuebles.mercadolibre.com.mx/venta/")

dom = html.fromstring(res.text)

xpath = "//div[contains(text(), 'Inmueble')]/following-sibling::ul//a[contains(@class,'ui-search-modal__link')]/@href"
url = dom.xpath(xpath)[0]

assert url == 'https://inmuebles.mercadolibre.com.mx/venta/_FiltersAvailableSidebar?filter=PROPERTY_TYPE'

既然scrapy和lxml的xpath应该是一样的,当然希望开头的代码在你的scrapy项目中也能正常工作。