2010-06-29 2 views
3

Предполагая, что у меня есть HTML прочитать в моей программе, как это:получить содержимое <a> тегов с помощью питона

<p><a href="http://vancouver.en.craigslist.ca/nvn/ret/1817849271.html">F/T &amp; P/T Sales Associate - Caliente Fashions</a> - <font size="-1"> (North Vancouver)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817804151.html">IMMEDIATE EMPLOYMENT WANTED!</a> - </p> 

<p><a href="http://vancouver.en.craigslist.ca/nvn/ret/1817796152.html">TRAVEL AGENT</a> - <font size="-1"> (NORTH VANCOUVER)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/bnc/ret/1817775400.html">Optical Sales Position</a> - <font size="-1"> (New Westminster)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817709780.html">Sales Clerk</a> - <font size="-1"> (Kits)</font></p> 

<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817676850.html">MARINE SALES</a> - <font size="-1"> (VANCOUVER (KITS))</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817608506.html">Retail Sales Associate</a> - <font size="-1"> (Vancouver)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817573985.html">Retail with small parts appliance background</a> - </p> 
<p><a href="http://vancouver.en.craigslist.ca/rds/ret/1817540938.html">Manager *Enjoyable work atmosphere</a> - <font size="-1"> (Langley Centre)</font></p> 

<p><a href="http://vancouver.en.craigslist.ca/bnc/ret/1817403652.html">Team Member - Retail Store - FT</a> - <font size="-1"> (Burnaby South)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/rds/ret/1817459155.html">STORE MANAGER-SHOE WAREHOUSE</a> - <font size="-1"> (South Surrey-Semiahmoo)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/pml/ret/1817448777.html">Retail Sales</a> - <font size="-1"> (Coquitlam)</font></p> 

Как захватить содержимое текстового узла? То, что я хотел бы в конечном итоге с печатает что-то похожее на этой линии в терминале:

http://vancouver.en.craigslist.ca/nvn/ret/1817849271.html - TRAVEL AGENT 

До сих пор у меня есть следующий код, который извлекает HREF ссылки штраф, но я не уверен, как извлечь данные сам. Я думаю о переопределении handle_data(self, data) из модуля sgmllib.py, но пока я не могу представить, как это сделать.

from sgmllib import SGMLParser 

class URLLister(SGMLParser): 
    def reset(self): 
     SGMLParser.reset(self) 
     self.urls = [] 

    def start_a(self, attrs): 
     href = [v for k, v in attrs if k == "href"] 
     if href: 
      self.urls.extend(href) 

Спасибо!

+1

Не используйте 'sgmllib', он устарел. Вместо этого используйте 'HTMLParser'. http://docs.python.org/library/htmlparser.html#module-HTMLParser –

ответ

4

Лично я хотел бы использовать lxml. После установки, получить то, что вы хотите просто:

from lxml import html 

tree = html.fromstring(open("data.html").read()) 

print [e.text_content() for e in tree.xpath("//a")] 
8

Простейшим вероятно BeautifulSoup (обязательно использовать 3.0.8 или выше 3.0.* релиз, не3.1.*, если вы не на Python 3 - см here !).

import BeautifulSoup 
soup = BeautifulSoup.BeautifulSoup(thehtmlstring) 

for anchor in soup.findAll('a'): 
    print anchor['href'], anchor.string 

BeautifulSoup изготовлять Юникод строка - если это проблема, обязательно кодировать их, как вы хотите, чтобы получить байтовые строки, как вы хотите их!

+0

Если после этого ДЕЙСТВИТЕЛЬНО НЕ ИСПОЛЬЗУЙТЕ 3.1. * (я должен прочитать все перед погружением в него) :) –

2

SGMLParser устарел в Python 2.6 и уйдет в 3.0. Возможно, вы захотите использовать модуль HTMLParser. Я никогда не использовал его раньше (я всегда использую BeutifulSoup для таких вещей), поэтому я решил, что узнаю, как это работает. Вот пример сценария, который я собрал, чтобы вы получили то, что хотите.

#!/usr/bin/env python 

from HTMLParser import HTMLParser 

class URLParser(HTMLParser): 
    def __init__(self): 
     self.in_link = False 
     self.links = [] 
     self.current_link = '' 
     HTMLParser.__init__(self) 

    def handle_starttag(self, tag, attrs): 
     if tag == 'a': 
      self.current_link = self.get_href_from_attrs(attrs) 
      self.in_link = True 

    def handle_endtag(self, tag): 
     if tag == 'a': 
      self.links.append(self.current_link) 
      self.in_link = False 

    def handle_data(self, data): 
     if self.in_link: 
      self.current_link = '%s - %s' % (self.current_link, data) 

    def get_href_from_attrs(self, attrs): 
     # The attrs dict is a list of tuples like: 
     # [('href', 'www.google.com'), ('class', 'some-class')] 
     for prop, val in attrs: 
      if prop == 'href': 
       return val 
     return '' 

if __name__ == '__main__': 
    the_html = ''' 
<p><a href="http://vancouver.en.craigslist.ca/nvn/ret/1817849271.html">F/T &amp; P/T Sales Associate - Caliente Fashions</a> - <font size="-1"> (North Vancouver)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817804151.html">IMMEDIATE EMPLOYMENT WANTED!</a> - </p> 

<p><a href="http://vancouver.en.craigslist.ca/nvn/ret/1817796152.html">TRAVEL AGENT</a> - <font size="-1"> (NORTH VANCOUVER)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/bnc/ret/1817775400.html">Optical Sales Position</a> - <font size="-1"> (New Westminster)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817709780.html">Sales Clerk</a> - <font size="-1"> (Kits)</font></p> 

<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817676850.html">MARINE SALES</a> - <font size="-1"> (VANCOUVER (KITS))</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817608506.html">Retail Sales Associate</a> - <font size="-1"> (Vancouver)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/van/ret/1817573985.html">Retail with small parts appliance background</a> - </p> 
<p><a href="http://vancouver.en.craigslist.ca/rds/ret/1817540938.html">Manager *Enjoyable work atmosphere</a> - <font size="-1"> (Langley Centre)</font></p> 

<p><a href="http://vancouver.en.craigslist.ca/bnc/ret/1817403652.html">Team Member - Retail Store - FT</a> - <font size="-1"> (Burnaby South)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/rds/ret/1817459155.html">STORE MANAGER-SHOE WAREHOUSE</a> - <font size="-1"> (South Surrey-Semiahmoo)</font></p> 
<p><a href="http://vancouver.en.craigslist.ca/pml/ret/1817448777.html">Retail Sales</a> - <font size="-1"> (Coquitlam)</font></p> 
    ''' 
    url_parser = URLParser() 
    url_parser.feed(the_html) 

    print '\n'.join(url_parser.links) 

Выход

http://vancouver.en.craigslist.ca/nvn/ret/1817849271.html - F/T - P/T Sales Associate - Caliente Fashions 
http://vancouver.en.craigslist.ca/van/ret/1817804151.html - IMMEDIATE EMPLOYMENT WANTED! 
http://vancouver.en.craigslist.ca/nvn/ret/1817796152.html - TRAVEL AGENT 
http://vancouver.en.craigslist.ca/bnc/ret/1817775400.html - Optical Sales Position 
http://vancouver.en.craigslist.ca/van/ret/1817709780.html - Sales Clerk 
http://vancouver.en.craigslist.ca/van/ret/1817676850.html - MARINE SALES 
http://vancouver.en.craigslist.ca/van/ret/1817608506.html - Retail Sales Associate 
http://vancouver.en.craigslist.ca/van/ret/1817573985.html - Retail with small parts appliance background 
http://vancouver.en.craigslist.ca/rds/ret/1817540938.html - Manager *Enjoyable work atmosphere 
http://vancouver.en.craigslist.ca/bnc/ret/1817403652.html - Team Member - Retail Store - FT 
http://vancouver.en.craigslist.ca/rds/ret/1817459155.html - STORE MANAGER-SHOE WAREHOUSE 
http://vancouver.en.craigslist.ca/pml/ret/1817448777.html - Retail Sales 

Update: После прохождения этого мало упражнений интерфейс для этого просто чувствует себя грубым, так что я просто буду придерживаться гораздо более чистого BeutifulSoup библиотека. См. Образец Алекса, чтобы посмотреть, как это делается.

+0

Мне нравится: 'for k, v в attrs: если k == 'href'; return v' –

+0

Хороший звонок. Я обновил свой пост. – sdolan

1

Пока мы сравниваем варианты, это Pyparsing фрагмент также дает место для каждой позиции, приведенное в <font> теге после закрытия <a> тега:

from pyparsing import makeHTMLTags, SkipTo 

a,aEnd = makeHTMLTags("A") 
font,fontEnd = makeHTMLTags("FONT") 
p,pEnd = makeHTMLTags("P") 

patt = (p + a("a") + SkipTo(aEnd)("posn") + aEnd + '-' + 
     font + SkipTo(fontEnd)("locn") + fontEnd + pEnd) 

for tokens,_,_ in patt.scanString(the_html): 
    print tokens.a.href, '-', tokens.posn, tokens.locn 

Дает:

http://vancouver.en.craigslist.ca/nvn/ret/1817849271.html - F/T &amp; P/T Sales Associate - Caliente Fashions (North Vancouver) 
http://vancouver.en.craigslist.ca/nvn/ret/1817796152.html - TRAVEL AGENT (NORTH VANCOUVER) 
http://vancouver.en.craigslist.ca/bnc/ret/1817775400.html - Optical Sales Position (New Westminster) 
http://vancouver.en.craigslist.ca/van/ret/1817709780.html - Sales Clerk (Kits) 
http://vancouver.en.craigslist.ca/van/ret/1817676850.html - MARINE SALES (VANCOUVER (KITS)) 
http://vancouver.en.craigslist.ca/van/ret/1817608506.html - Retail Sales Associate (Vancouver) 
http://vancouver.en.craigslist.ca/rds/ret/1817540938.html - Manager *Enjoyable work atmosphere (Langley Centre) 
http://vancouver.en.craigslist.ca/bnc/ret/1817403652.html - Team Member - Retail Store - FT (Burnaby South) 
http://vancouver.en.craigslist.ca/rds/ret/1817459155.html - STORE MANAGER-SHOE WAREHOUSE (South Surrey-Semiahmoo) 
http://vancouver.en.craigslist.ca/pml/ret/1817448777.html - Retail Sales (Coquitlam) 
0
#download BeautifulSoup library for python 
from Beautiful import * 

fh = open('data.html') 
html = fh.read() 
soup = BeautifulSoup(html) 

tags = soup('a') 

for tag in tags: 
    print tag.contents[0] 

 Смежные вопросы

  • Нет связанных вопросов^_^