Próbując wyodrębnić tekst ze strony internetowej za pomocą pięknejSoup. Chcesz przejść na wyjście zupy.Findall () jako wejście do dalszych oczyszczania danych za pomocą modułu RE

Prosta zmienna wejście tekstowe działa, ale jeśli przejdę na wyjście zupa.Findall (), jego rzucanie następujący błąd.

Traceback (ostatnie połączenie ostatnie): Plik "Scratep2.py", linia 18, w URL = Re.Search ('http: // [az.] / [A-ZA-Z /% 0-9-] ', UNIV) Plik "/usr/lib/Python2.7 /re.py ", linia 142, w poszukiwaniu Powrót _Compile (wzór, flagi) .search (string) TypeError: Oczekiwany ciąg lub bufor

Zmienne drukowanie zupa.Findall () działa. Jak przejść bezpośrednio przejść wyjście zupy.findall () jako polecenie wejściowe ro re.search.

pełny kod źródłowy

from BeautifulSoup import BeautifulSoup
import urllib2
import os
import re
page=urllib2.urlopen(url)


soup = BeautifulSoup(open("rr-ss.html").read())
univ=soup.findAll('div',{'id':'divBrand1'})

print univ
text = '<span class="normaltextblue"><a href="http://www.roya3d.com/zdae/bug/coastdfilm-coated%20tab">Rocks</a></span>&nbsp;&nbsp;&nbsp;'


#following command throwing error 
url = re.search( 'http://[a-z.]*/[A-Za-z/%0-9-]*', univ)

#following line working fine
url = re.search( 'http://[a-z.]*/[A-Za-z/%0-9-]*', text)

if url:
    found = url.group(0)    
    print found
0
Vikram 24 listopad 2013, 12:02

3 odpowiedzi

Najlepsza odpowiedź

findAll Zwraca listę elementów HTML. Lista nie jest ciągami, a elementy HTML nie są również ciągami, dzięki czemu nie można zastosować do nich regex, chyba że najpierw przekonwertujesz je do ciągów. Więc odpowiedź na twoje rzeczywiste pytanie: "Jak zdać wyjście findAll do regex.search()", jest użycie unicode(univ).

Ale twój regex wydaje się źle - oprócz czegoś innego nie pasuje do adresu URL w swoim przykładzie, który ma cyfrę w lokalizacji sieciowej.

Ponadto tam powinno tylko jeden element z danym {x0}} (to jest punkt identyfikatora w HTML, jest wyjątkowy w dokumencie). Tak więc findAll i tak wydaje się źle, chyba że celowo pozwalasz na złamane HTML.

Prawdopodobnie powinieneś zrobić coś takiego:

url = soup.find('div', {'id':'divBrand1'}).a['href']

Musisz również zdecydować, jak poradzić sobie z możliwością, że dokument nie zawiera danych, których szukasz. Kod, który pokazałem rzuty wyjątki, ale możesz sprawdzić, czy None jest zwrócona z .find() lub .a Jeśli wolisz obsługiwać go bez wyjątków. Zadzwoń has_key(), aby zobaczyć, czy href jest obecny na elemencie <a>.

0
Steve Jessop 24 listopad 2013, 10:37

Po znalezieniu tego problemu można po prostu wydrukować "DIR (obiekt)" i "Typ (obiekt)", więc expectl expect to lista, możesz po prostu uzyskać dostęp do elementu Findall.

Nawiasem mówiąc, z tego, co robisz, zastanawiam się, czy chcesz zdobyć href o określonym identyfikatorze? Proponuję, abyś mógł użyć selektora CSS i na przykład użyć ("href"), na przykład

#get the divs
divbrands = soup.select('#divBrand1')
for divbrand in divbrands:
    #get all <a></a> tags
    links = divbrand.select('a')
    for link in links:
        #get all the href
        print link.get('href')

Możesz także napisać go w jednej linii:

hrefs = [link.get('href') for link in soup.select('#divBrand1 > a')]
0
paramiao 24 listopad 2013, 08:21

Miałem problem z skrobaniem, gdzie musieliśmy dostać renderowaną zawartość lub widoczną zawartość w typowej przeglądarce. W przypadku poniżej, bez wyłączonego znacznika jest zagnieżdżone w stylu znacznik i nie jest widoczny w wielu przeglądarkach, które sprawdzałem. Istnieją inne warianty, takie jak zdefiniowanie wyświetlania ustawienia tagu klasy. Następnie używając tej klasy dla div.

<html>
  <title>  Title here</title>

  <body>

    lots of text here <p> <br>
    <h1> even headings </h1>

    <style type="text/css"> 
        <div > this will not be visible </div> 
    </style>


  </body>

</html>

Jedno opublikowane powyżej jest:

html = Utilities.ReadFile('simple.html')
soup = BeautifulSoup.BeautifulSoup(html)
texts = soup.findAll(text=True)
visible_texts = filter(visible, texts)
print(visible_texts)


[u'\n', u'\n', u'\n\n        lots of text here ', u' ', u'\n', u' even headings ', u'\n', u' this will not be visible ', u'\n', u'\n']

To rozwiązanie z pewnością ma w wielu przypadkach w wielu przypadkach i wykonuje zadanie całkiem dobrze, ale w opublikowanej powyżej HTML zachowuje tekst, który nie jest renderowany. Po wyszczepieniu, więc kilka rozwiązań pojawiło się tutaj BeautifulSoup Get_Text Nie pasuje do wszystkich tagów i javascript i tutaj renderowane HTML do zwykłego tekstu Korzystanie z Pythona.

import nltk

%timeit nltk.clean_html(html)
was returning 153 us per loop

... lub używając HTML2Text

betterHTML = html.decode(errors='ignore')
%timeit html2text.html2text(betterHTML)
%3.09 ms per loop
0
Community 23 maj 2017, 12:12