2016-08-11 4 views
1

vor kurzem habe ich begonnen, mehrere Seiten zu kratzen, aber die Struktur der Seite ist wirklich schwer zu kratzen. Es hat viele "nth type" -Elemente, die keine Klassen für jedes Selbst haben. Aber ihre Eltern teilen dieselbe Klasse. Ich arbeite mit BeautifulSoup und es war toll, bis ich diese schreckliche Code sah ...Python BeautifulSoup scrape Nth-Art von Elementen

<div class="detail-50"> 
    <div class="detail-panel-wrap"> 
     <h3>Contact details</h3> 
      Website: <a href="http://www.somewebsitefrompage.com">http://www.somewebsitefrompage.com</a><br />Email: <a href="mailto:somemailfrompage.com">somemailfrompage.com</a><br />Tel: 11111111 111 
        </div> 
         </div> 

Für jetzt ist es ok scheint, aber ich möchte Webseite, E-Mail und Tel abzuschaben. separat. Ich habe versucht, mit vielen Methoden wie

website = soup.select('div.detail-panel-wrap')[1].text` 

Aber funktioniert nicht .. Jetzt kommt sehr großes Problem, wenn andere Elemente derselben Klasse wie Kontaktdaten haben:

<div class="detail-50"> 
    <div class="detail-panel-wrap"> 
     <h3>Public address</h3> 
      Mr Martin Austin, Some street, Some city, some ZIP 
        </div> 
         </div> 

Dieses ist für Adresse ist, auch Ich brauche das auch gekratzt. Es gibt viele andere "div" Namen wie diese beiden. Hat jemand eine Lösung? Wenn jemand nicht verstanden hat, kann ich es besser, sorry für schlechte Erklärung erklären ..

UPDATE
Mit einigen Wählern Software, die ich herausgefunden habe, wie es sein soll, aber es ist in Python schwierig, es zu schreiben. . Hier ist, wie Telefon von Seite zu finden:

div#ContentPlaceHolderDefault_cp_content_ctl00_CharityDetails_4_TabContainer1_tpOverview_plContact.detail-panel div.detail-50:nth-of-type(1) div.detail-panel-wrap    

Dies ist für Adresse ist

div#ContentPlaceHolderDefault_cp_content_ctl00_CharityDetails_4_TabContainer1_tpOverview_plContact.detail-panel div.detail-50:nth-of-type(2) div.detail-panel-wrap 

Dies ist für Website-

div.detail-50 a:nth-of-type(1) 

Und dieser für den Kontakt E-Mail

div.detail-panel-wrap a:nth-of-type(2) 

Hinweis: ContentPlaceHolderDefault_cp_content_ctl00_CharityDetails_4_TabContainer1_tpOverview_plContact

ist Mutter div class an der Spitze all diesen.

Hat jemand eine Idee, wie man diese in BS4 Python schreibt?

Antwort

0

Wenn es mehrere divs mit Klasse Detail-Panel-wrap, können Sie die h3 Text verwenden, um diejenigen, die Sie wollen:

contact = soup.find("h3", text="Contact details").parent 
address = soup.find("h3", text="Public address").parent 

Wenn wir es auf eine Probe laufen können Sie sehen, wir beide divs erhalten:

In [22]: html = """ 
    ....: <div class="detail-50"> 
    ....:  <div class="detail-panel-wrap"> 
    ....:   <h3>Contact details</h3> 
    ....:    Website: <a href="http://www.somewebsitefrompage.com">http://www.somewebsitefrompage.com</a><br />Email: <a href="mailto:somemailfrompage.com">somemailfrompage.com</a><br />Tel: 11111111 111 
    ....:      </div> 
    ....:  </div> 
    ....:  <div class="detail-50"> 
    ....:   <div class="detail-panel-wrap"> 
    ....:    <h3>Public address</h3> 
    ....:     Mr Martin Austin, Some street, Some city, some ZIP 
    ....:   </div> 
    ....:  </div> 
    ....:  <div class="detail-panel-wrap"> 
    ....:  < h3>foo/h3> 
    ....:  </div> 
    ....:  <div class="detail-panel-wrap"> 
    ....:   <h3>bar/h3> 
    ....:  </div> 
    ....: </div> 
    ....:  """ 

In [23]: from bs4 import BeautifulSoup 

In [24]: soup = BeautifulSoup(html,"lxml") 

In [25]: contact = soup.find("h3", text="Contact details").parent 

In [26]: address = soup.find("h3", text="Public address").parent 

In [27]: print(contact) 
<div class="detail-panel-wrap"> 
<h3>Contact details</h3> 
      Website: <a href="http://www.somewebsitefrompage.com">http://www.somewebsitefrompage.com</a><br/>Email: <a href="mailto:somemailfrompage.com">somemailfrompage.com</a><br/>Tel: 11111111 111 
        </div> 

In [28]: print(address) 
<div class="detail-panel-wrap"> 
<h3>Public address</h3> 
       Mr Martin Austin, Some street, Some city, some ZIP 
     </div> 

es können auch andere Möglichkeiten, aber ohne die vollständige hTML-Struktur zu sehen, ist es nicht möglich zu wissen ist.

Für Ihre bearbeiten, müssen Sie einfach die Selektoren verwenden, mit select_one:

telephone = soup.select_one("#ContentPlaceHolderDefault_cp_content_ctl00_CharityDetails_4_TabContainer1_tpOverview_plContact.detail-panel div.detail-50:nth-of-type(1) div.detail-panel-wrap")    

address = soup.select_one("#ContentPlaceHolderDefault_cp_content_ctl00_CharityDetails_4_TabContainer1_tpOverview_plContact.detail-panel div.detail-50:nth-of-type(2) div.detail-panel-wrap") 


website = soup.select_one("div.detail-50 a:nth-of-type(1)") 

email = soup.select_one("div.detail-panel-wrap a:nth-of-type(2)") 

Aber es gibt keine Garantie, nur weil die Wähler in Chrom-Tools etc .. arbeiten, dass sie an der Quelle arbeiten Du kommst zurück.

+0

Hallo, ich danke Ihnen für Ihre Hilfe, Sie können ein Update sehen, das ich angehängt habe, wie es direkt sein sollte, aber das Problem ist, wie man es in Python-Code schreibt. – Ukii

+0

@Ukii, die Selektoren, die Sie in Ihrer Bearbeitung hinzugefügt haben, scheinen etwas zu sein, das Sie von Chrome-Tools kopiert haben und funktionieren möglicherweise nicht auf der tatsächlichen Quelle, aber unabhängig davon müssen Sie buchstäblich genau so wie sie in einer Auswahl sind –