从浏览器复制的 CSS 选择器 returns 在 Python 中使用 BeautifulSoup4 的不同结果

The copied CSS selector from the browser returns a different result using BeautifulSoup4 in Python

通常当我想从网站上抓取特定文本时,我会右键单击该文本并 select 检查。然后在 HTML 代码中,我寻找我感兴趣的文本和 right-click -> 'copy' -> 'copy selector'.

然后我将刚刚复制的文本字符串粘贴到 soup.select('enter copied text here') 中并将其保存到一个变量中。然后我可以执行文本剥离功能来获取我需要的关键文本。

现在对于我正在处理的情况,我想在 header h1: cars.com/cars/used/.

中获取此网页上显示的汽车总数

这是我的代码:

import requests
from bs4 import BeautifulSoup as bs

url = "https://www.cars.com/used"
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.41 Safari/537.36'}

res = requests.get(url,headers = headers)
res.raise_for_status()

soup = bs(res.text, 'html.parser')

total_cars_element = soup.select('body > div.listing > div.container.listing-container.has-header-sticky > div.row.flex-nowrap.no-gutters > div:nth-child(1) > div:nth-child(1) > div')

print(total_cars)
# the above prints an empty list.

我真的只想知道为什么这不起作用。我知道还有其他解决方法,正如我在上面的代码中提到的那样。但我真的想坚持使用 soup.select 方法。

非常感谢任何见解! 谢谢!

问题源于通过 Python 获取的 HTML 与在浏览器中生成的不同。尝试打印 soup 并亲自查看。

您查询中的一个特定标记很麻烦。在浏览器中,它看起来像这样:

<div class="container listing-container has-header-sticky">

但是您的 Python 代码看到的是:

<div class="container listing-container">

将您的选择器更改为:

body > div.listing > div.container.listing-container > div.row.flex-nowrap.no-gutters > div:nth-child(1) > div:nth-child(1) > div

你会得到预期的结果。


此行为被认为是正常的,因为您尝试抓取的页面是 动态。这意味着 JavaScript 添加或删除原始 HTML 页面的某些部分 页面加载后。

如果您想使用 Python 抓取动态网页,您需要的不仅仅是 Beautiful Soup。有关该主题的更多信息,请参阅 https://scrapingant.com/blog/scrape-dynamic-website-with-python

很好的答案,你也可以使用

total_cars_element = soup.select('h1.title')
print(total_cars_element[0].text)

更多关于 CSS Select