【问题标题】:Using BeautifulSoup to find multiple elements with the same CSS Class使用 BeautifulSoup 查找具有相同 CSS 类的多个元素
【发布时间】:2017-07-21 22:58:45
【问题描述】:

我正在尝试使用 BeautifulSoup 的 find_all() 来搜索具有标签“div”和类“wisbb_name”的元素。我正在抓取的 HTML 来自 http://www.foxsports.com/mlb/scores。我的最终目标是根据该网站获取当天开始的所有投手的姓名。下面是投手名称的 HTML

<div class="wisbb_name">M. Fiers</div>

所有投手的 HTML 代码都具有相同的类,只是与之关联的文本不同。我已经使用下面的代码行从 find_all() 中获取所有结果并获取与之关联的文本。

for el in soup.find():
print(el.get_text()) 

这很好,问题是 find_all() 没有找到我想要它找到的元素,无论我改变了多少参数。根据 BeautifulSoup documentation 的说法,下面的代码行应该找到具有类“wisbb_name”和标签“div”的元素。

variable = soup.find_all("div", class_="wisbb_name")
print(variable)

打印变量时,我只得到一个空列表。我不确定我是否在 python 中以错误的方式处理这个问题,或者我需要了解更多有关 HTML 工作原理的信息。我有最新版本的 BeautifulSoup,我正在使用 Python 3.6.2。我当前的完整代码如下。

import requests
from bs4 import BeautifulSoup
page = requests.get("url from top because I can't use 3 links")
soup = BeautifulSoup(page.content, "lxml")
for el in soup.find_all("div", class_="wisbb_name"):
    print(el.get_text())

【问题讨论】:

  • 我在您提供的 URL 中找不到 wisbb_name 类。您确定这是正确的网址吗?
  • 如果你去http://www.foxsports.com/mlb/scores,右键点击chrome,然后点击inspect,然后点击打开的新菜单左上角的光标图标。这应该是这样,当您单击网站的一部分时,它会选择检查菜单中的元素。现在只需点击投手的名字,它就会带您进入我正在谈论的元素。
  • 为了澄清,请务必查看尚未开始的游戏。看起来该网站在现场比赛期间不显示当前投手。继续向下滚动,直到您看到显示可能投手的未来比赛。

标签: python web-scraping beautifulsoup


【解决方案1】:

文本使用 JavaScript 呈现。 先用dryscrape渲染页面

import bs4 as bs
import dryscrape

url = ("http://www.foxsports.com/mlb/scores")
session = dryscrape.Session()
session.visit(url)
dsire_get = session.body()
soup = bs.BeautifulSoup(dsire_get,'lxml')
for el in soup.find_all("div", class_="wisbb_name"):
    print(el.get_text())

输出:

A. Sanchez
E. Santana
J. Shields
I. Kennedy
T. Williams
J. Hoffman
M. Scherzer
Z. Godley
C. Sale
R. Nolasco
C. Sabathia
A. Moore
J. García
A. Wood
T. Cahill
J. Samardzija

或者使用硒... 首先安装它:

sudo pip3 install selenium

那就找个驱动https://sites.google.com/a/chromium.org/chromedriver/downloads

import bs4 as bs
from selenium import webdriver  
browser = webdriver.Chrome()
url = ("http://www.foxsports.com/mlb/scores")
browser.get(url)
html_source = browser.page_source
browser.quit()
soup = bs.BeautifulSoup(html_source, "lxml")
for el in soup.find_all("div", class_="wisbb_name"):
    print(el.get_text())

或 PyQt5:

from PyQt5.QtGui import *  
from PyQt5.QtCore import *  
from PyQt5.QtWebKit import *  
from PyQt5.QtWebKitWidgets import QWebPage
from PyQt5.QtWidgets import QApplication
import bs4 as bs
import sys

class Render(QWebPage):  
    def __init__(self, url):  
        self.app = QApplication(sys.argv)  
        QWebPage.__init__(self)  
        self.loadFinished.connect(self._loadFinished)  
        self.mainFrame().load(QUrl(url))  
        self.app.exec_()  

    def _loadFinished(self, result):  
        self.frame = self.mainFrame()  
        self.app.quit()  

url = "http://www.foxsports.com/mlb/scores" 
r = Render(url)  
result = r.frame.toHtml()
soup = bs.BeautifulSoup(result,'lxml')
for el in soup.find_all("div", class_="wisbb_name"):
    print(el.get_text())

【讨论】:

  • 谢谢!感谢您如此迅速地回复。效果很好。
猜你喜欢
  • 2022-01-12
  • 2016-08-14
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多