2009-09-08 5 views
7

Я пытаюсь создать веб-скребок, который будет анализировать веб-страницу публикаций и извлекать авторов. Скелетная структура веб-страницы заключается в следующем:Python web scraping с использованием HTML-тегов с атрибутами

<html> 
<body> 
<div id="container"> 
<div id="contents"> 
<table> 
<tbody> 
<tr> 
<td class="author">####I want whatever is located here ###</td> 
</tr> 
</tbody> 
</table> 
</div> 
</div> 
</body> 
</html> 

Я пытался использовать BeautifulSoup и LXML до сих пор для решения этой задачи, но я не уверен, как обрабатывать два Div теги и td, потому что у них есть атрибуты. В дополнение к этому, я не уверен, должен ли я больше полагаться на BeautifulSoup или lxml или на комбинацию обоих. Что мне делать?

На данный момент мой код выглядит так, как это показано ниже:

import re 
    import urllib2,sys 
    import lxml 
    from lxml import etree 
    from lxml.html.soupparser import fromstring 
    from lxml.etree import tostring 
    from lxml.cssselect import CSSSelector 
    from BeautifulSoup import BeautifulSoup, NavigableString 

    address='http://www.example.com/' 
    html = urllib2.urlopen(address).read() 
    soup = BeautifulSoup(html) 
    html=soup.prettify() 
    html=html.replace('&nbsp', '&#160') 
    html=html.replace('&iacute','&#237') 
    root=fromstring(html) 

Я понимаю, что многие операторы импорта может быть излишним, но я просто скопировал все, что в данный момент было более исходного файла.

EDIT: Я полагаю, что я не делал этого достаточно ясно, но у меня есть несколько тегов на странице, которые я хочу очистить.

ответ

11

Это мне не ясно из вашего вопроса, почему вы должны беспокоиться о div тегов - насчет делать просто:

soup = BeautifulSoup(html) 
thetd = soup.find('td', attrs={'class': 'author'}) 
print thetd.string 

На HTML вы даете, бег это испускает именно:

####I want whatever is located here ### 

, который кажется тем, что вы хотите. Возможно, вы можете лучше указать, что вам нужно, и этот супер-простой сниппет не делает - несколько td тегов всех классов author, о которых вам нужно подумать (все? Только некоторые из них?), Возможно, отсутствуют какие-либо такой тег (что вы хотите сделать в этом случае) и тому подобное. Трудно сделать вывод, какие именно ваши спецификации, просто из этого простого примера и избыточного кода ;-).

Edit: если, в соответствии с последним замечанием OP, есть несколько таких TD-теги, один за автора:

thetds = soup.findAll('td', attrs={'class': 'author'}) 
for thetd in thetds: 
    print thetd.string 

... то есть, не намного сложнее, вообще -)

+0

Спасибо, Алекс. У меня несколько авторов на странице, поэтому у меня будет несколько тегов td. Как я могу перебирать каждую из них? – GobiasKoffi

1

BeautifulSoup, безусловно, является каноническим парсером/процессором HTML. Но если у вас есть только этот вид фрагмента, который вам нужно сопоставить, вместо создания целого иерархического объекта, представляющего HTML, pyparsing упрощает определение основных и конечных HTML-тегов в качестве части создания более крупного поискового выражения:

from pyparsing import makeHTMLTags, withAttribute, SkipTo 

author_td, end_td = makeHTMLTags("td") 

# only interested in <td>'s where class="author" 
author_td.setParseAction(withAttribute(("class","author"))) 

search = author_td + SkipTo(end_td)("body") + end_td 

for match in search.searchString(html): 
    print match.body 

Функция pyHPSMLTags Pyparsing делает намного больше, чем просто испускает "<tag>" и "</tag>" выражения.Он также работает:

  • без корпуса соответствия тегов
  • "<tag/>" синтаксических
  • ноль или более атрибутов в открывающем теге
  • атрибуты определены в произвольном порядке
  • имен атрибутов с пространствами имен
  • значений атрибутов в одиночных, двойных или без котировок
  • промежуточный пробел между тегом и символами или имя атрибута, '=', d значение
  • атрибутов доступны после разбора как именованных результаты

Этих распространенные ошибки при рассмотрении с помощью регулярных выражений для HTML выскабливания.

6

или вы могли бы использовать pyquery, поскольку BeautifulSoup не активно поддерживается больше, см http://www.crummy.com/software/BeautifulSoup/3.1-problems.html

первых, установить pyquery с

easy_install pyquery 

тогда ваш сценарий может быть столь же просто, как

from pyquery import PyQuery 
d = PyQuery('http://mywebpage/') 
allauthors = [ td.text() for td in d('td.author') ] 

pyquery использует синтаксис селектора css, знакомый с jQuery, который я нахожу более интуитивным, чем BeautifulSoup. Он использует lxml снизу и намного быстрее, чем BeautifulSoup. Но BeautifulSoup является чистым питоном и, следовательно, работает и с движком приложений Google

5

Библиотека lxml теперь является стандартом для разбора html в python. Сначала интерфейс может показаться неудобным, но он очень полезен для того, что он делает.

Вы должны позволить библиотеке обращаться к специалисту xml, например к экранированным объектам;

import lxml.html 

html = """<html><body><div id="container"><div id="contents"><table><tbody><tr> 
      <td class="author">####I want whatever is located here, eh? &iacute; ###</td> 
      </tr></tbody></table></div></div></body></html>""" 

root = lxml.html.fromstring(html) 
tds = root.cssselect("div#contents td.author") 

print tds   # gives [<Element td at 84ee2cc>] 
print tds[0].text # what you want, including the 'í'