Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Web
  • » Проблема с парсингом кривых вебсайтов [RSS Feed]

#1 Сен. 20, 2011 08:43:50

Rockocat
От:
Зарегистрирован: 2011-09-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

Я начинающий питонер. Увлекся парсингом. Для теста решил пропарсить тайтлы сайтов, а чтобы не заморачиваться с поиском линков, сделал цикл перебора по цифре в адресе. Не суть важно. Проблема в том, что обе известные библиотеки lxml и beatifull soup спотыкаются на некоторых сайтах.

Вот скрипт на lxml, работает прекрасно, без проблем

import lxml.html
t = lxml.html.parse("http://www.python.org")
print t.find(".//title").text
Но спотыкается на сайте bb8.com, который пустой, не имеет даже тайтла

import lxml.html
t = lxml.html.parse("http://www.bb8.com")
print t.find(".//title").text
Выдает ошибку
print t.find(“.//title”).text
AttributeError: ‘NoneType’ object has no attribute ‘text’

Что вполне логично, ведь нет тайтла NoneType
И программа прекращает работать. Вопрос. Как обойти ошибку? Нужно создать условие, что если NoneType, то проходи дальше. Искал в гугле. Пишут, что надо получить значение атрибута, но честно говоря, я так и не понял их очень сложный код и он там был применим к другой ситуации.

Насчет beatifull soup, справляется с bb8 без проблем, но спотыкается на сайте bb5.com и прекращает работу
import urllib
import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(urllib.urlopen("http://www.bb5.com"))
print soup.title.string
Traceback (most recent call last):
File “/Documents/py-docs/ur.py”, line 3, in <module>
soup = BeautifulSoup.BeautifulSoup(urllib.urlopen("http://www.bb5.com“))
File ”/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py“, line 84, in urlopen
return opener.open(url)
File ”/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py“, line 205, in open
return getattr(self, name)(url)
File ”/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib.py", line 349, in open_http
‘got a bad status line’, None)
IOError: ('http protocol error', 0, ‘got a bad status line’, None)



Офлайн

#2 Сен. 20, 2011 09:29:21

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

1) Насчет lxml - у вас ошибка не NoneType, у вас ошибка в другом.
t.find(“.//title”) - Это идет поиск тайтла. lxml тайтл найти не может, ибо его нету и отдает вместо него None, после этого вы берёте “.text”, что есть вызов атрибута “text” у найденного обьекта, так как у вас нету ноды, ибо поиск вернул вам None, то вы пытаетесь взять атрибут “text” у None, что вызывавет ошибку “AttributeError”, потому что у NoneType нету атрибута text. В качестве решения лично я бы разбил на два шага и делал проверку после первого, а если поточнее, то вот так:

import lxml.html

link = "http://www.python.org"
t = lxml.html.parse(link)
title_node = t.find(".//title")
if title_node:
print title_node.text
else:
print u"Кукиш вам, а не тайтл для сайта {0}".format(link)
2) Насчет beatifull soup. Он не ругается ни на что. До супа дело не доходит. У вас ругается urllib.Причем ругается на нехорошие вещи, как видно - неправильная статус-строка. Можно поцепить игнорирование ошибки IOError для urllib вот таким вот образом:

import urllib
import BeautifulSoup

link = "http://www.bb5.com"
try:
page = urllib.urlopen(link)
except IOError:
page = "" #Это для, чтобы было что скормить супу, но скорей всего приведет к ошибкам, подобным с lxml

soup = BeautifulSoup.BeautifulSoup(page)
print soup.title.string



Офлайн

#3 Сен. 20, 2011 21:09:39

Rockocat
От:
Зарегистрирован: 2011-09-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

Спасибо за подсказку, она навела меня на правильную мысль. Если использовать ваш код к lxml, то получим вот такую ошибку.
Warning (from warnings module):
if title_node:
FutureWarning: The behavior of this method will change in future versions. Use specific ‘len(elem)’ or ‘elem is not None’ test instead.

Я устроил небольшие шаманские танцы с бубном по отгону злых духов и получил вот такой рабочий код.

import lxml.html

t = lxml.html.parse("http://www.python.org")
f=t.find(".//title")

if f == None:
print "NONE"
else:
print t.find(".//title").text
В любом случае спасибо, без вас бы мое развитие пошло бы в сторону говнокода.



Офлайн

#4 Сен. 21, 2011 09:55:58

Rockocat
От:
Зарегистрирован: 2011-09-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

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

  if d == None:
print "No title or error"
Однако ему тоже крышу сорвало на сайте b26.com Выяснилось, что это баг обходится, если в print f.title.string убрать string

Теперь все работает ИДЕАЛЬНО, пропарсил 500 сайтов за 20 минут. Ни одной ошибки. По тайтлам нашел парочку интересных сайтов для себя :)



Офлайн

#5 Сен. 21, 2011 13:37:56

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

Насчет lxml - то был warning, warning - это предупреждение, ошибка - это exception.
Если конкретно, то lxml не нравится именно такое использование и в будущем использование вида “if title_node:” будет невозможно, поэтому они просят вместо конструкции вида “if title_node:” использовать конструкцию вида “if title_node is not None:”. Это приводит нас к:

import lxml.html

t = lxml.html.parse("http://www.python.org")
f=t.find(".//title")

if f is not None:
print f.text
else:
print "No Title"
Ворнинга не будет.
П.С. Интересуют подробности относительно выпадания lxml. Суп это хорошо, но lxml быстрее…



Отредактировано (Сен. 21, 2011 13:41:16)

Офлайн

#6 Сен. 21, 2011 18:58:47

Rockocat
От:
Зарегистрирован: 2011-09-20
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

Ему чем-то не нравится сайт b93.com
Выдает вот такое

Traceback (most recent call last):
File "/Users/RockoCat/Documents/py-docs/lx.py", line 2, in <module>
t = lxml.html.parse("http://www.b93.com")
File "/Library/Python/2.7/site-packages/lxml-2.3-py2.7-macosx-10.6-intel.egg/lxml/html/__init__.py", line 692, in parse
return etree.parse(filename_or_url, parser, base_url=base_url, **kw)
File "lxml.etree.pyx", line 2942, in lxml.etree.parse (src/lxml/lxml.etree.c:54187)
File "parser.pxi", line 1528, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:79485)
File "parser.pxi", line 1557, in lxml.etree._parseDocumentFromURL (src/lxml/lxml.etree.c:79768)
File "parser.pxi", line 1457, in lxml.etree._parseDocFromFile (src/lxml/lxml.etree.c:78843)
File "parser.pxi", line 997, in lxml.etree._BaseParser._parseDocFromFile (src/lxml/lxml.etree.c:75698)
File "parser.pxi", line 564, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:71739)
File "parser.pxi", line 645, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:72614)
File "parser.pxi", line 583, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:71927)
IOError: Error reading file 'http://www.b93.com': failed to load external entity "http://www.b93.com"



Офлайн

#7 Сен. 22, 2011 10:47:48

diam123
От:
Зарегистрирован: 2008-10-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

Проблема с парсингом кривых вебсайтов

Гуголь говорит о каком то баге в lxml.
Приведенную выше ошибку можно убить вот таким вот макаром:

import lxml.html

link = "http://www.python.org"
try:
t = lxml.html.parse(link)
f=t.find(".//title")
except IOError:
print "Troubles on {0}".format(link)
else:
if f is not None:
print f.text
else:
print "No Title"
Предлагаю модифицировать код таким образом:
import lxml.html

link = "http://www.python.org"
try:
t = lxml.html.parse(link)
f=t.find(".//title")
except IOError:
print "Troubles on {0}, trying with soup".format(link)
try:
page = urllib.urlopen(link)
except IOError:
print "Error fetching {0} with soup".format(link)
page = ""
soup = BeautifulSoup.BeautifulSoup(page)
print soup.title
else:
if f is not None:
print f.text
else:
print "No Title"



Офлайн

  • Начало
  • » Web
  • » Проблема с парсингом кривых вебсайтов[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version