漂亮汤无法找到标签

9

我目前正在尝试使用Python 3.6中的requests和BeautifulSoup模块进行练习,但遇到了一个问题,在其他问题和答案中似乎找不到任何信息。

似乎在页面的某个地方,Beautiful Soup停止识别标签和ID。我正在尝试从这样的页面提取Play-by-play数据:

http://www.pro-football-reference.com/boxscores/201609080den.htm

import requests, bs4

source_url = 'http://www.pro-football-reference.com/boxscores/201609080den.htm'
res = requests.get(source_url)
if '404' in res.url:
    raise Exception('No data found for this link: '+source_url)

soup = bs4.BeautifulSoup(res.text,'html.parser')

#this works
all_pbp = soup.findAll('div', {'id' : 'all_pbp'})
print(len(all_pbp))

#this doesn't
table = soup.findAll('table', {'id' : 'pbp'})
print(len(table))

使用Chrome中的检查器,我可以看到表格确实存在。我也尝试在HTML后半部分的“div”和“tr”上使用它,但似乎不起作用。我已经尝试了标准的“html.parser”,以及lxml和html5lib,但什么都没用。
我在这里做错了什么,还是HTML或其格式中有些东西阻止了BeautifulSoup正确地找到这些后续标记?我遇到过类似页面由这家公司运行(hockey-reference.com,basketball-reference.com)的问题,但已经能够在其他网站上正确使用这些工具。
如果是HTML的问题,那么有没有更好的工具/库来帮助提取这些信息呢?
谢谢您的帮助, BF

你的语句 table = soup.findAll('table', {'id' : 'pbp'}) 并不是“不工作”,它只是找不到 id = pbpdiv 元素。 - Dmitriy Fialkovskiy
@DmitriyFialkovskiy 我试图最终创建一个特定比赛的比赛记录的Excel文件。一旦我可以将注意力集中在那个表上,我有信心可以循环遍历tr和td标签以从中获取文本,并使用openpyxl将其放入Excel中。我想我的问题最终是为什么bs4在html中找不到标签。它似乎可以在注释之前找到任何标签,但在注释之后却找不到 - 注释会影响解析吗?是否有任何方法可以准确地从注释后提取标签? - Big Fore
2
如果是这样,页面上的JavaScript需要在抓取之前先加载。这篇文章似乎有一种方法可以做到这一点 - https://dev59.com/O2sz5IYBdhLWcg3wOVH5。 - qwertyuip9
1
@qwertyuiop9 谢谢!这正是我在寻找的。我没有意识到BeautifulSoup可能不包含我通过浏览器查看的所有HTML。我会尝试使用Selenium或Dryscrape来看看能否解决问题。再次感谢。 - Big Fore
1
这个回答解决了您的问题吗?使用Python抓取带有JavaScript的网页 - user202729
显示剩余3条评论
2个回答

5

在进行GET请求获取URL后,BS4将无法执行网页的javascript。我认为被关注的表格是由客户端异步加载的javascript。

因此,在爬取HTML之前需要先运行客户端JavaScript。这篇帖子描述了如何实现这一点!


再次感谢,那就是问题所在。玩Dryscrape有所帮助。我猜我又有一个要学习的库了。 - Big Fore
截至2022年10月,这个答案似乎已经过时了,因为那些推荐的软件包已经不再维护了! - Farid Alijani

0

好的,我明白问题所在了。你正在尝试解析一个注释,而不是普通的 HTML 元素。 对于这种情况,你应该使用 BeautifulSoup 中的 Comment,像这样:

import requests
from bs4 import BeautifulSoup,Comment

source_url = 'http://www.pro-football-reference.com/boxscores/201609080den.htm'
res = requests.get(source_url)
if '404' in res.url:
    raise Exception('No data found for this link: '+source_url)

soup = BeautifulSoup(res.content,'html.parser')

comments=soup.find_all(string=lambda text:isinstance(text,Comment))

for comment in comments:
    comment=BeautifulSoup(str(comment), 'html.parser')
    search_play = comment.find('table', {'id':'pbp'})
    if search_play:
        play_to_play=search_play

@Big Fore,有反馈吗?我的回答有帮助吗? - Dmitriy Fialkovskiy
你的回答对我的学习过程肯定有帮助,但并不是我遇到问题的解决方案。我的问题在于找到注释后面的任何标签。事实证明,我在浏览器中看到的HTML是通过JavaScript加载的,因此没有显示在请求文本中,但需要进一步的库来解析。谢谢你的帮助Dmitry。 - Big Fore
你的意思是要捕捉特定评论后面的文本或标签吗?我不是很明白。 - Dmitriy Fialkovskiy

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