【问题标题】:Can't figure out Beautifulsoup find() command for this HTML无法找出此 HTML 的 Beautifulsoup find() 命令
【发布时间】:2018-07-26 20:05:44
【问题描述】:

我正在尝试使用 python 和 Beautiful soup 从页面中抓取一些信息,但我似乎无法写出我需要的正确路径,html 是:

<div class="operator active" data-operator_name="Etisalat" data- 
operator_id="5"><div class="operator_name_etisalat"></div></div>

我正在尝试获取该运营商名称“Etisalat”,我已经做到了这一点:

def list_contries():

select = Select(driver.find_element_by_id('international_country'))
select.select_by_visible_text('France')
request = requests.get("https://mobilerecharge.com/buy/mobile_recharge?country=Afghanistan&operator=Etisalat")
content = request.content
soup = BeautifulSoup(content, "html.parser")
# print(soup.prettify())
prov=soup.find("div", {"class": "operator active"})['data-operator_name']
# prov = soup.find("div", {"class": "operator deselected"})
print(prov)
operator = (prov.text.strip())

但这只是返回一个 NoneType ..所以有些不对劲,谁能告诉我我做错了什么?谢谢。

【问题讨论】:

  • 您的解决方案对我有用!只需将您的 html 复制为字符串,用 BeautifulSoup 解析它并使用您的 find(...) &gt;&gt;&gt; 'Etisalat'。你能把剩下的代码贴出来吗
  • 我推测在soup 中,该类实际上不是operator active,而是在DOM 中。这可能是您没有得到结果的原因。
  • 用其余代码编辑了问题。谢谢
  • 第一个问题是请求不处理javascript,并且您获得的页面与您通过检查元素看到的页面不同。您应该通过在新选项卡 [ctrl]+U 中打开页面源来检查它。

标签: python html web-scraping beautifulsoup find


【解决方案1】:

您可以使用 CSS 选择器。 CSS 选择器[data-operator_name] 将选择具有data-operator_name 属性的任何标签。美汤示例:

data = """<div class="operator active" data-operator_name="Etisalat" data-
operator_id="5"><div class="operator_name_etisalat"></div></div>"""

from bs4 import BeautifulSoup

soup = BeautifulSoup(data, 'lxml')

print(soup.select_one('[data-operator_name]')['data-operator_name'])

这将打印:

Etisalat

编辑:

要选择具有“data-operator_name”属性的多个标签,请使用.select() 方法:

data = """<div class="operator active" data-operator_name="Etisalat" data-
operator_id="5"><div class="operator_name_etisalat"></div></div>"""

from bs4 import BeautifulSoup

soup = BeautifulSoup(data, 'lxml')
for tag in soup.select('[data-operator_name]'):
    print(tag['data-operator_name'])

【讨论】:

  • 嗯,谢谢伙计,但我需要找到多个运算符,而不仅仅是一个。代码需要是 findall() 而不是 find() 我只是用 find() 检查和测试。
  • @miloshIra 然后只使用select(),而不是select_one()。我更新了我的答案。
  • 现在它正在抓取各种东西......一堆我不需要的东西。我认为 find() 和 find_all 如果我设法让它工作起来会更好,因为它还包括 div 和 class。
【解决方案2】:

不知何故,当我从浏览器访问链接时,除非我检查元素,否则我无法看到您所追求的字段。因此,我在回答中使用了 Selenium。

from bs4 import BeautifulSoup
from selenium import webdriver

scrapeLink = 'https://mobilerecharge.com/buy/mobile_recharge?country=Afghanistan&operator=Etisalat'
driver = webdriver.Firefox(executable_path = 'C:\geckodriver.exe')
driver.get(scrapeLink)
html = driver.execute_script('return document.body.innerHTML')
driver.close()

soup = BeautifulSoup(html,'html.parser')
operator = len(soup.find_all('div', class_ = 'operator'))

for i in range(operator):
    print(soup.find_all('div', class_ = 'operator')[i].get('data-operator_name'))

输出:

Roshan
Etisalat
MTN
Wireless

【讨论】:

  • 你是对的。这是因为请求模块没有运行/获取 java 脚本。实际页面来源与请求收集的页面来源不同。
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 2020-11-18
  • 2020-10-11
  • 2021-12-06
  • 2017-03-15
  • 2018-01-03
  • 1970-01-01
  • 2012-10-28
相关资源
最近更新 更多