2015-09-19 4 views
3

Я написал код, чтобы извлечь URL-адрес и название книги, используя BeautifulSoup со страницы.Извлечение содержимого <a> tag

Но это не извлекая название книги Astounding Истории Супер-Наука апреля 1930 между > и </a> тегов.

Как я могу извлечь название книги?

Я попробовал метод findnext, рекомендованный в другом вопросе, но я получаю AttributeError.

HTML:

<li> 
     <a class="extiw" href="//www.gutenberg.org/ebooks/29390" title="ebook:29390">Astounding Stories of Super-Science April 1930</a> 
     <a class="image" href="/wiki/File:BookIcon.png"><img alt="BookIcon.png" height="16" src="//www.gutenberg.org/w/images/9/92/BookIcon.png" width="16"/></a> 
     (English) 
    </li> 

код ниже:

def make_soup(BASE_URL): 
    r = requests.get(BASE_URL, verify = False) 
    soup = BeautifulSoup(r.text, 'html.parser') 
    return soup 

def extract_text_urls(html): 
    soup = make_soup(BASE_URL) 

    for li in soup.findAll('li'): 
     try: 
      try: 
       print li.a['href'], li.a['title'] 
       print "\n" 
      except KeyError: 
       pass 
     except TypeError: 
      pass 

extract_text_urls(filename) 
+1

свяжите страницу, которую вы пытаетесь, чтобы очистить. –

+1

Также непонятно, что такое метод findnext. –

+0

страница, которую я пытаюсь очистить: https://www.gutenberg.org/wiki/Science_Fiction_(Bookshelf) – Sam

ответ

3

Вы должны использовать атрибут элемента text. Следующие работы для меня:

def make_soup(BASE_URL): 
    r = requests.get(BASE_URL) 
    soup = BeautifulSoup(r.text, 'html.parser') 
    return soup 

def extract_text_urls(html): 
    soup = make_soup(BASE_URL) 

    for li in soup.findAll('li'): 
     try: 
      try: 
       print li.a['href'], li.a.text 
       print "\n" 
      except KeyError: 
       pass 
     except TypeError: 
      pass 

extract_text_urls('http://www.gutenberg.org/wiki/Science_Fiction_(Bookshelf)') 

я получаю следующий результат для элемента в вопросе

//www.gutenberg.org/ebooks/29390 Astounding Stories of Super-Science April 1930

1

Я не видел, как вы можете извлечь текст внутри тега. Я хотел бы сделать что-то вроде этого:

from bs4 import BeatifulSoup as bs 
from urllib2 import urlopen as uo 
soup = bs(uo(html)) 

for li in soup.findall('li'): 
    a = li.find('a') 
    book_title = a.contents[0] 
    print book_title 
3

Согласно the BeautifulSoup documentation.string собственность должна выполнить то, что вы пытаетесь сделать, отредактировав исходный список таким образом:

# ... 
     try: 
      print li.a['href'], li.a['title'] 
      print "\n" 
      print li.a.string 
     except KeyError: 
      pass 
    # ... 

Вы, вероятно, хотите, чтобы окружить его с чем-то вроде

if li.a['class'] == "extiw": 
    print li.a.string 

, так как, в вашем примере, только якоря класса extiw содержат название книги.

Спасибо @wilbur за то, что вы указали оптимальное решение.

+0

Это может сработать, но я считаю, что лучше всего использовать '.text', как я описал в своем ответе ниже – wpercy

+0

@wilbur: он, конечно, выглядит лучше, спасибо. Однако документация BS4, с которой я связан, не упоминает об этом. Где вы его нашли? При ближайшем рассмотрении он упоминает ['.string'] (http://www.crummy.com/software/BeautifulSoup/bs4/doc/#string), может ли это быть лучшей практикой? –

+0

Я использую '.text' какое-то время, я думаю, что я должен был прочитать об этом в версии до bs4? – wpercy

1

Чтобы получить только текст, который не находится внутри каких-либо меток, используйте метод get_text(). Он находится в документации here.

Я не могу проверить его, потому что я не знаю URL страницы, которую вы пытаетесь очистить, но вы можете просто сделать это с помощью тега li, так как там, кажется, нет никакого другого текста.

Попробуйте заменить это:

for li in soup.findAll('li'): 
    try: 
     try: 
      print li.a['href'], li.a['title'] 
      print "\n" 
     except KeyError: 
      pass 
    except TypeError: 
     pass 

с этим:

for li in soup.findAll('li'): 
    try: 
     print(li.get_text()) 
     print("\n") 
    except TypeError: 
     pass