BeautifulSoup没有找到表行

时间:2018-04-06 19:25:35

标签: python web-scraping beautifulsoup

我正在尝试从CBSsports.com golf tournament results抓取信息但是使用漂亮的汤只返回<tr> <tbody><table>个孩子中的第一个中的四个表行 <table cellpadding="2" cellspacing="1" class="data" defaultsort="currentpos" enablesort="true" id="Leaderboard" onsort="Leaderboard.sort" width="620"> <tr class="label" recordid="{id}"></tr> </table> 中的一个}。

检查谷歌浏览器返回: Screenshot of chrome inspect

美丽的汤回归:

html

我已尝试lxml parsersrequests.get制作汤,并尝试urllib.requestsstack打开与网站的连接,但所有结果都是相同。我有什么想法吗?

最终所需的输出,我希望能够从表中提取大部分数据并放入pandas数据帧,但是一旦我可以访问每个表数据点,我应该能够解决这个问题。 / p>

2 个答案:

答案 0 :(得分:1)

如果您查看页面的来源,那么您会发现id="Leaderboard"的表格不包含具有播放器数据的实际行,但使用javascript进行渲染。
requests.geturllib.request用于执行HTTP请求,因此不会执行这些javascript渲染(您的浏览器会为您执行此操作)。
要获取数据,您必须使用一些呈现数据的框架。您可以结帐Splash 使用scrapy with splash也是一种选择。

答案 1 :(得分:1)

在您抓取的页面上,div#Leaderboard在浏览器中运行的javascript呈现它们之前不包含任何行。独立requestsurllib.request都不适合您。我建议您使用非常受欢迎的requests-html作者创建的此程序包requests

from requests_html import HTMLSession

session = HTMLSession()
r = session.get('http://www.cbssports.com/golf/leaderboard/pga-tour/1186083/houston-open')
r.html.render()
table = r.html.find('#Leaderboard', first=True)

现在该表包含行,我们可以使用以下代码获取它们:

rows = table.find("tr[id^='Leaderboard']")

如您所见,我们成功找到了行:

>>> len(rows)
144

有几行你可能不感兴趣,例如:title,highlight,label和adRow。这就是我使用tr[id^='Leaderboard']选择器来过滤它们的原因。它以tr开头的所有Leaderboard为目标(例如,包含数据的第一行的ID为Leaderboard401338)。您可以阅读有关substring matching attribute selectors或CSS选择器的更多信息here