2017-02-05 3 views
0

Ich benutze Beautiful Soup, um Daten aus einer HTML-Tabelle zu lesen. Warum bekomme ich kein Ergebnis vom Tisch und wie repariere ich es? Mein Code gibt "None" zurück.So lesen Sie HTML-Tabellendaten w Schöne Suppe? Rückgabe 'Keine'

Ich sehe, dass es Javascript in der Seitenquelle gibt und gelesen haben, dass ein Problem sein könnte. Die URL führt einen Bericht aus, der in die Tabelle eingegeben wird.

Ich habe soup.prettify() verwendet, um den HTML-Code zu überprüfen, und es scheint nicht den vollständigen Quellcode zu geben. Ich bin mir nicht sicher, ob das ein Problem ist.

Hier ist der HTML-Code der Tabelle und die erste Datenreihe:

<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> 

Hier ist mein Versuch mit Schöner Suppe:

from urllib.request import urlopen 
from bs4 import BeautifulSoup 

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

ich auch XPath versucht habe, aber eine leere Liste erhalten:

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]') 

UPDATE: ich denke, die tabl e Ich versuche zu verwenden ist dynamisch erstellt; Wie würde ich meinen Code ändern, um dies zu berücksichtigen? Ich habe auch versucht, find_all zu verwenden, um meine Arbeit zu überprüfen, aber es bringt nicht jede Tabelle im HTML zurück, nur die erste. Warum ist das?

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

Hier ist der Ausgang:

[<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>] 
+0

Interessant, dass die Tabelle, die Sie mit find_all erhalten, keine Klasse hat. Das würde erklären, warum die Versuche, mit class_ zu finden, nicht funktionieren. – rasmeister

Antwort

0

Es sieht für mich wie Sie die alte Form in früheren Versionen von schöner Suppe und den neueren verwendet Vermischung werden.

Ich würde versuchen: soup.find("table", class_="table-data")

Dies ist die Syntax für die neueren Versionen der schönen Suppe. Ich hoffe, dass Sie das verwenden.

Ich habe keine schöne Suppe installiert, so kann ich nicht überprüfen, aber Sie könnten es versuchen.

+0

Ich habe eine modifizierte Version von diesem versucht, die das _ mit = ersetzt, da Ihr Vorschlag mir einen Syntaxfehler gab. Mit 'print (soup.find ('table', class _ = 'table-data'))' gibt mir noch keiner. Irgendwelche anderen Gedanken oder Vorschläge zu einer alternativen Lösung? –

+0

Ja, du hast recht, dass sollte '=' nicht ':' - wird bearbeiten. Welche Version von Beautiful Soup benutzt du? 'class' ist ein reserviertes Wort in Python und verwendet daher ab 4.1.2 class_, um es zu repräsentieren. – rasmeister

+0

Eine andere Sache, die Sie versuchen könnten, wäre 'sup.select (table.table-data)' oder 'soup.find (" table ", attrs = {" class ":" table-data "})' – rasmeister

0

Sie haben einen Fehler in Ihrem finden Anruf.

Sie suchen nach einem Tabelle Element, das beide Tabellendaten habenund Tabelle Klassen. Aber wie Sie sehen können, hat die Tabelle nur die Klasse Tabellendaten, nicht Tabelle eins. Ersetzen Sie den Code mit:

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

UPDATE: Es scheint, dass die Webseite, wie Sie in der Update gesagt wird dynamisch erstellt. Also drucken Sie bitte die vollständige HTML-Webseite (oder speichern Sie sie in eine Datei) und umgehen Sie diesen Code (verwenden Sie nicht den Code, den Sie in Google Chrome oder anderen Browser Inspektor sehen, haben sie einige Code nach dem Laden von Dokumenten generiert.).

  • Wenn Sie alles, was Sie brauchen, mit diesem Code haben, ist das alles.
  • Wenn Sie nicht das haben, was Sie brauchen, denken Sie bitte daran, Ghost webkit web client anstelle von urllib/requests zu verwenden, um HTML der Webseite dynamisch zu erstellen. Dann können Sie reines JavaScript verwenden, um das Element zu erhalten, nach dem Sie suchen, oder Beautiful Soup verwenden.
+0

Ich habe das mit versucht Kein Erfolg; es gibt immer noch keine zurück. Eine andere seltsame Sache, die ich bemerkte, ist, wenn ich das Element in Google Chrome inspiziere, ist die Klasse für die Tabelle 'class =" Tabellendaten Tabelle Tabelle-Hover "' nicht 'class =" Tabellendaten ", wie es im Quellcode zeigt . –