使用BeautifulSoup和请求解析网站返回None



我是一个编程初学者,同时从事我的一个项目。为此,我试图解析网站上的数据,以制作一个使用这些数据的工具。我发现BeatifulSoup和Request是实现这一点的常用工具,但不幸的是,我似乎无法使其发挥作用。它总是返回值None或一个错误,其中显示:

"TypeError:"NoneType"对象不可调用">

我做错什么了吗?是不是可能无法解析一些网站数据,而我被限制访问或其他什么?

如果有其他方法可以访问数据,我也很高兴听到。

这是我的代码:

from bs4 import BeautifulSoup
import requests
pickrates = {}      # dict to store winrate of champions for each position
source = requests.get("http://u.gg/lol/champions/aatrox/build?role=top").text
soup = BeautifulSoup(source, "lxml")
value = soup.find("div", class_="content-section champion-ranking-stats")
print(value.prettify())

请记住,当您使用requests模块请求网页时,您将只获得该页面的html。我的意思是这个模块不能呈现JavaScript。

试试这个代码:

import requests
source = requests.get("http://u.gg/lol/champions/aatrox/build?role=top").text
print(source)

然后搜索您手动提供的类名(ctrl+f(,根本没有这样的元素。这意味着它们是由ajax等其他请求生成的。它们是在加载初始html页面后以某种方式创建的。因此,在Beautiful汤进入聚会之前,即使在响应对象的.text属性中也无法获得它们。

一种方法是使用Selenium或任何其他处理JS的库。

这个问题似乎是由JavaScript事件侦听器引起的(当我使用beautifulsoup抓取网页时,无法找到html标记(。我建议您使用selenium来处理这个问题。因此,让我们在发送请求和获取返回页面源时应用selenium,然后使用BeautifulSoup对其进行解析

不要忘记从下载浏览器驱动程序https://www.selenium.dev/documentation/getting_started/installing_browser_drivers/并将其与代码放在同一目录中。

下面的代码示例是将selenium与Firefox一起使用:

from selenium import webdriver
from bs4 import BeautifulSoup
URL = 'http://u.gg/lol/champions/aatrox/build?role=top'
browser = webdriver.Firefox()
browser.get(URL)
soup = BeautifulSoup(browser.page_source, 'html.parser')
time.sleep(1)
browser.close()
value = soup.find("div", class_="content-section champion-ranking-stats")
print(value.prettify())

您的预期输出如下:

>>> print(value.prettify())
<div class="content-section champion-ranking-stats">
<div class="win-rate meh-tier">
<div class="value">
48.4%
</div>
<div class="label">
Win Rate
</div>
</div>
<div class="overall-rank">
<div class="value">
49 / 58
</div>
<div class="label">
Rank
</div>
</div>
<div class="pick-rate">
<div class="value">
3.6%
</div>
<div class="label">
Pick Rate
</div>
</div>
<div class="ban-rate">
<div class="value">
2.3%
</div>
<div class="label">
Ban Rate
</div>
</div>
<div class="matches">
<div class="value">
55,432
</div>
<div class="label">
Matches
</div>
</div>
</div>

最新更新