Форум сайта python.su
Я начинающий питонер. Увлекся парсингом. Для теста решил пропарсить тайтлы сайтов, а чтобы не заморачиваться с поиском линков, сделал цикл перебора по цифре в адресе. Не суть важно. Проблема в том, что обе известные библиотеки lxml и beatifull soup спотыкаются на некоторых сайтах.
Вот скрипт на lxml, работает прекрасно, без проблем
import lxml.html
t = lxml.html.parse("http://www.python.org")
print t.find(".//title").text
import lxml.html
t = lxml.html.parse("http://www.bb8.com")
print t.find(".//title").text
import urllib
import BeautifulSoup
soup = BeautifulSoup.BeautifulSoup(urllib.urlopen("http://www.bb5.com"))
print soup.title.string
Офлайн
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)
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
Офлайн
Спасибо за подсказку, она навела меня на правильную мысль. Если использовать ваш код к 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
Офлайн
Вот что выяснилось, код на lxml все-таки проглючил на каком-то очень хитром сайте. Я тогда взял ваш код на супе и слегка его переделал после первого глюка, тоже по принципу
if d == None:
print "No title or error"
Офлайн
Насчет 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"
Отредактировано (Сен. 21, 2011 13:41:16)
Офлайн
Ему чем-то не нравится сайт 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"
Офлайн
Гуголь говорит о каком то баге в 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"
Офлайн