【问题标题】:Python beautiful soup doesn't locate a span elementPython 美汤没有找到 span 元素
【发布时间】:2019-04-11 12:38:25
【问题描述】:

我正在以下 Instagram 页面上测试 Instagram:https://www.instagram.com/acmilan/ 并尝试获取帖子元素(现在 = '4,552 个帖子')。 如果我检查页面,HTML 看起来就像随附的屏幕截图。 我定位该元素的代码是:

driver = webdriver.Chrome
soup = BeautifulSoup(driver.page_source, 'html.parser')
elements = soup.find_all("ul", text=re.compile("posts"))
print(len(elements))

但这没有找到任何东西。 然后,我尝试了:

elements = soup.find_all("span", text=re.compile("posts"))
print(len(elements))

还是什么都没有。 然后,我尝试了:

elements = soup.find_all(True, text=re.compile('posts'))

再一次,什么都没有。

这似乎是一项很容易的任务,但不知何故我找不到解决方案。有什么建议? 谢谢

【问题讨论】:

  • 数据是通过 JavaScript 呈现的,因此无法通过 BeautifulSoup 访问,因为 BS 只能访问静态 HTML。您可能需要使用 Selenium 来呈现 ReactJS 内容,然后可以使用 BeautifulSoup 解析这些内容,类似于此问答:Scraping elements rendered using React JS with BeautifulSoup
  • 我正在尝试编辑我的问题,但找不到解决方法。我忘了提到“soup = BeautifulSoup(driver.page_source, 'html.parser')”和驱动来自 selenium。
  • 在这种情况下,您的代码在我运行时可以正常工作。尝试使用:elements = soup.find('span', {'class': "g47SY "}); print(elements.text)
  • @davedwards 谢谢戴夫。问题是,我需要使用文本“post”而不是类值来查找元素,因为这经常发生变化。你能想出一个基于关键字“post”的解决方案吗?谢谢
  • 是的,我可以提供解决方案,但首先您检查过以下任何答案吗?

标签: python-3.x beautifulsoup


【解决方案1】:

这是我使用此代码解决问题的方法。请确保安装 re 模块。

from bs4 import BeautifulSoup
import requests
import re
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}

url = 'https://www.instagram.com/acmilan/'
page = requests.get(url, headers=headers)
soup = BeautifulSoup(page.text, 'html.parser')
find = soup.findAll('meta')
meta = re.findall('g,.+\ Posts', str(find))[0]
print(meta.replace('g, ', '').replace('Posts', ''))

Output: 4,552 

【讨论】:

  • 非常感谢。请问你为什么使用'meta'而不是'span'和'li'之类的标签信息?该元素在屏幕上可见,所以如果我使用 selenium page_source 作为源,我不应该能够找到它吗?
  • javascript brochacho
  • @Angelo 代码对你有用吗?您将无法获得所需的数据,因为网站上运行着脚本,尤其是 instagram。您要查找的信息恰好位于 标记中。我使用re 使用正则表达式提取数据并获取信息。
  • 非常感谢您的帮助。即使您的解决方案确实有帮助,但在我的具体情况下,我不得不走另一条路。帖子的数量不在 javascript 中,而是通过 li 和 span 元素显示在浏览器中。所以我决定建立一个所有 div、span 和 li 元素的列表,检查它们的文本值,直到找到帖子的数量。我需要这种效率较低的解决方案,因为今天帖子编号位于元元素内,但明天可能不会。所有这一切中唯一的“常数”实际上就是“帖子”这个词。无论如何,谢谢!
【解决方案2】:

要获得不需要BeautifulSoupselenium 的帖子计数,请使用regex 或更好地使用json

import requests
import re
import json

url = 'https://www.instagram.com/acmilan/'
page = requests.get(url)
postCount = re.search('timeline_media":{"count":(\d+)', page.text)
print('regex: ' + postCount.groups()[0])

# using json
jString = re.search('window._sharedData = (\{.+?\});</script>', page.text)
json_data = json.loads(jString.groups()[0])
postCount = json_data['entry_data']['ProfilePage'][0]['graphql']['user']['edge_owner_to_timeline_media']['count']
print('json: ' + str(postCount))

# to show all json object
# print(json_data)

【讨论】:

  • 非常感谢您的回答。即使它完成了这项工作,也不能保证“帖子”编号总是在时间线媒体内。不幸的是,我需要一个更长期的解决方案,以应对将帖子元素移动到代码其他部分的情况。如果您可以考虑一种纯粹使用“帖子”一词的方法,而无需其他任何方法来找到我所需要的号码。谢谢!
  • 正则表达式可能很容易更改/破坏,但不是 json,它自 2013 年或更早以来的格式相同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
相关资源
最近更新 更多