我是一个编程初学者,同时从事我的一个项目。为此,我试图解析网站上的数据,以制作一个使用这些数据的工具。我发现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>