Beautiful Soup无法找到我想要的HTML部分。

6

我已经使用BeautifulSoup进行网页抓取有一段时间了,但这是我第一次遇到这样的问题。我试图在代码中选择数字101,172,但即使我使用“ .find”或“ .select”,输出始终只有标签,而没有数字。之前我处理类似的数据收集时没有遇到任何问题。

<div class="legend-block legend-block--pageviews">
      <h5>Pageviews</h5><hr>
      <div class="legend-block--body">
        <div class="linear-legend--counts">
          Pageviews:
          <span class="pull-right">
            101,172
          </span>
        </div>
        <div class="linear-legend--counts">
          Daily average:
          <span class="pull-right">
            4,818
          </span>
        </div></div></div>

我使用了:

res = requests.get(wiki_page, timeout =None)
soup = bs4.BeautifulSoup(res.text, 'html.parser')
ab=soup.select('span[class="pull-right"]')
#print(i)
print(ab)

输出:

[<span class="pull-right">\n<label class="logarithmic-scale">\n<input 
class="logarithmic-scale-option" type="checkbox"/>\n        Logarithmic scale      
</label>\n</span>, <span class="pull-right">\n<label class="begin-at- 
zero">\n<input class="begin-at-zero-option" type="checkbox"/>\n        Begin at 
zero      </label>\n</span>, <span class="pull-right">\n<label class="show- 
labels">\n<input class="show-labels-option" type="checkbox"/>\n        Show 
values      </label>\n</span>]

此外,我正在寻找的数据编号是动态的,因此我不确定Javascript是否会影响BeautifulSoup。


2
你是怎么尝试获取这个值的呢?我们需要至少一小段代码来检查可能出现在你代码中的问题。 - meissner_
1
如果你使用BeautifulSoup解析HTML片段,然后对span标签执行find_all操作,并在返回结果上应用.text方法,那么你将得到101,172。 - iamklaus
2
可能是使用Python和BeautifulSoup进行动态数据网络爬虫的重复问题。 - Andriy Ivaneyko
1个回答

4

试试这个:

from bs4 import BeautifulSoup as bs

html='''<div class="legend-block legend-block--pageviews">
      <h5>Pageviews</h5><hr>
      <div class="legend-block--body">
        <div class="linear-legend--counts">
          Pageviews:
          <span class="pull-right">101,172
          </span>
        </div>
        <div class="linear-legend--counts">
          Daily average:
          <span class="pull-right">
            4,818
          </span>
        </div></div></div>'''
soup = bs(html, 'html.parser')
div = soup.find("div", {"class": "linear-legend--counts"})
span = div.find('span')
text = span.get_text()
print(text)

输出:

101,172

简单来说,只需要一行代码:

soup = bs(html, 'html.parser')
result = soup.find("div", {"class": "linear-legend--counts"}).find('span').get_text()

编辑:

由于OP发布了另一个可能是此问题的副本的问题,他已经找到了答案。对于寻找类似问题答案的其他人,我将在此问题中发布被接受的答案。可以在这里找到。

如果你使用requests.get获取页面,那么javascript代码将不会被执行。因此应该使用Selenium。它将模仿用户行为,用浏览器打开页面,从而可以执行js代码。

要开始使用Selenium,需要使用pip install selenium安装。然后,使用以下代码检索你的项目:

from selenium import webdriver

browser = webdriver.Firefox()
# List of the page url and selector of element to retrieve.
wiki_pages = [("https://tools.wmflabs.org/pageviews/?project=en.wikipedia.org&platform=all-access&agent=user&range=latest-20&pages=Star_Wars:_The_Last_Jedi",
               ".summary-column--container .legend-block--pageviews .linear-legend--counts:first-child span.pull-right"),]
for wiki_page in wiki_pages:
    url = wiki_page[0]
    selector = wiki_page[1]
    browser.get(wiki_page)
    page_views_count = browser.find_element_by_css_selector(selector)
    print page_views_count.text
browser.quit()

注意: 如果需要运行无头浏览器,请考虑使用PyVirtualDisplayXvfb的包装器)来运行无头WebDriver测试,有关详细信息,请参见'如何在Xvfb中运行Selenium?'。


我需要对许多页面执行此过程,因此我选择使用soup.select('html')选择整个HTML标签,并将其赋值给变量html,该过程与您的相同。然而,在变量html中,我仍然无法获取值。这可能是因为它是根据页面变化的动态数据吗? - user7157075
请给我一个示例网址。 - Ishara Madhawa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接