【问题标题】:How to read HTML table data w Beautiful Soup? Returning 'None'如何用 Beautifulsoup 读取 HTML 表格数据?返回“无”
【发布时间】:2017-06-22 19:39:57
【问题描述】:

我正在使用 Beautiful Soup 从 HTML 表中读取数据。为什么我没有从表格中得到结果,我该如何解决?我的代码返回“无”。

我看到页面源代码中有 javascript,并且已经阅读了这可能是一个问题。 url 运行输入到表中的报告。

我使用soup.prettify() 来检查 HTML,它似乎没有给我完整的源代码。我不确定这是否是个问题。

这是表格的 HTML 和第一个数据行:

    <table data-toggle="table"
        data-show-columns="true"
        data-show-export="true"
        data-show-toggle="true"
        class="table-data">
        <thead>
            <tr>
                <th data-field="RouteId" data-sortable="true">Route ID</th>
                <th data-field="RouteName" data-sortable="true">Route Name</th>
                <th data-field="TripId" data-sortable="true">Trip ID</th>
                <th data-field="TripName" data-sortable="true">Trip Name</th>
                <th data-field="InstanceId" data-sortable="true">INST ID</th>
                <th data-field="InstanceDate" data-sortable="true">INST Date</th>
                <th data-field="InstanceStatus" data-sortable="true">INST Status</th>
                <th data-field="InstanceCapacity" data-sortable="true">INST Cap.</th>
                <th data-field="NumOrders" data-sortable="true">Num. ORDs</th>
                <th data-field="OrderId" data-sortable="true">ORD ID</th>
                <th data-field="OrderType" data-sortable="true">ORD Type</th>
                <th data-field="OrderStatus" data-sortable="true">ORD Status</th>
                <th data-field="VehicleYear" data-sortable="true">VEH Year</th>
                <th data-field="VehicleMake" data-sortable="true">VEH Make</th>
                <th data-field="VehicleModel" data-sortable="true">VEH Model</th>
                <th data-field="VehicleRefNo1" data-sortable="true">VEH RefNo1</th>
                <th data-field="vehicleVin" data-sortable="true">VEH Vin</th>
                <th data-field="DriverId" data-sortable="true">DRV ID</th>
                <th data-field="DriverName" data-sortable="true">DRV Name</th>
                <th data-field="ScheduledPickupDateTime" data-sortable="true">Sch. Pick</th>
                <th data-field="ActualPickupPickupDateTime" data-sortable="true">Act. Pick</th>
                <th data-field="DeliveredDateTime" data-sortable="true">Hand. Rec.</th>
                <th data-field="HandheldDateTime" data-sortable="true">Del.</th>
            </tr>
        </thead>
        <tbody>

            <tr>
                <td>160</td>
                <td>8 LEG: MEM to PRES</td>
                <td>187</td>
                <td>Trip 1 - Leg 7</td>
                <td>740685</td>
                <td>2017-02-01</td>
                <td>Active</td>
                <td>9.00000</td>
                <td>9</td>
                <td>9110734</td>
                <td>LoadLegChild</td>
                <td>InRoute</td>
                <td>2015</td>
                <td>Jeep</td>
                <td>Patriot</td>
                <td>2000047350</td>
                <td>1C4NJPFBXFD318536</td>
                <td>1</td>
                <td>User, System</td>
                <td>2017-02-01 02:05 AM</td>
                <td>2017-02-01 02:20 AM</td>
                <td></td>
                <td></td>
            </tr>

这是我对 Beautiful Soup 的尝试:

from urllib.request import urlopen
from bs4 import BeautifulSoup

page = urlopen(url)
soup = BeautifulSoup(page,'lxml')
print(soup.find('table',{'class':'table-data table'}))

我也尝试过 xpath,但收到一个空列表:

import requests
from lxml import html
NewPage = requests.get(url)
tree = html.fromstring(NewPage.content)
tree.xpath('//*[@id="content"]/div[2]/div[2]/div[2]/div[2]/table/tbody/tr[1]/td[1]')

更新:我认为我尝试使用的表是动态创建的;我将如何更改我的代码来解决这个问题?我也尝试使用find_all 来检查我的工作,但它不会带回 HTML 中的每个表格,只有第一个表格。这是为什么呢?

page = requests.get(url)
pageText = page.text
soup = BeautifulSoup(pageText,'lxml')
print(soup.find_all('table'))

这是输出:

[<table cellpadding="0" cellspacing="0" id="Login1">
<tr>
<td>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="UserName">Username</label>
<input class="form-control" id="Login1_UserName" name="Login1$UserName" type="text"/>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="Password">Password</label>
<input class="form-control" id="Login1_Password" name="Login1$Password" type="password"/>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<input id="Login1_RememberMe" name="Login1$RememberMe" type="checkbox"/><label for="Login1_RememberMe">Remember my login</label>
</div>
<div class="col-md-6 text-right">
<input class="btn btn-default" id="Login1_Login" name="Login1$Login" type="submit" value="Login"/>
</div>
</div>
<p>
</p>
</td>
</tr>
</table>]

【问题讨论】:

  • 有趣的是,您使用 find_all 获得的表没有类。这可以解释为什么使用 class_ 进行查找的尝试不起作用。

标签: javascript html web-scraping beautifulsoup


【解决方案1】:

在我看来,您正在将早期版本的美汤中使用的旧形式与新形式混为一谈。

我会尝试: soup.find("table", class_="table-data")

这是新版本美丽汤的语法。希望这就是您正在使用的。

我没有安装漂亮的汤,所以我无法验证,但你可以试试看。

【讨论】:

  • 我尝试了一个修改版本,将 _ 替换为 = 因为你的建议给了我一个语法错误。使用print(soup.find('table', class_='table-data')) 仍然没有。关于替代解决方案的任何其他想法或建议?
  • 是的,你说得对,应该是 '=' 而不是 ':' - 将编辑。你用的是什么版本的美汤? 'class' 是 Python 中的保留字,因此从 4.1.2 开始,他们使用 class_ 来表示它。
  • 您可以尝试的另一件事是soup.select(table.table-data)soup.find("table", attrs={"class": "table-data"})
【解决方案2】:

您的 find 调用中有一个错误

您正在搜索同时具有 table-data table 类的 table 元素。但是,如您所见,该表只有 table-data 类,没有 table 类。将您的代码替换为:

print(soup.find('table',{'class':'table-data'}))

更新:好像你在更新中说的网页是动态创建的。因此,请打印完整的 HTML 网页(或将其保存到文件中)并解决该代码(不要使用您在 Google Chrome 或其他浏览器检查器中看到的代码,它们会在之后生成一些代码文件加载。)。

  • 如果您拥有该代码所需的一切,就是这样。
  • 如果您没有所需的东西,请考虑使用Ghost webkit web 客户端,而不是urllib/requests,来动态创建网页HTML。然后,您可以使用纯 JavaScript 来获取您要搜索的元素,或者也可以使用 Beautiful Soup。

【讨论】:

  • 我试过这个没有成功;它仍然返回无。我注意到的另一件奇怪的事情是,如果我检查 Google Chrome 中的元素,表格的类是 class="table-data table table-hover" 而不是源代码中显示的 class="table-data
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-27
相关资源
最近更新 更多