(Python 3.4.2) Во-первых, я новичок в python — больше, чем новичок, но меньше, чем средний пользователь.
Я пытаюсь отобразить буквальный текст URL-адреса на странице с помощью lxml. Я думаю, что у меня ПОЧТИ есть это, но я что-то упускаю. Я могу получить фактические ссылки, но не их названия.
Пример - отсюда,
<a class="yt-uix-sessionlink yt-uix-tile-link spf-link yt-ui-ellipsis yt-ui-ellipsis-2" dir="ltr" aria-describedby="description-id-588180" data-sessionlink="ei=6t2FVJLtEsOWrAbQ24HYAg&ved=CAcQvxs&feature=c4-videos-u" href="/watch?v=I2AcJG4112A&list=UUrtZO4nmCBN4C9ySmi013oA">Zombie on Omegle!</a>
Я хочу получить это:
'Zombie on Omegle!'
(Я сделаю этот HTML-тег более читабельным для вас, ребята)
<a class="yt-uix-sessionlink yt-uix-tile-link spf-link yt-ui-ellipsis yt-ui-ellipsis-2"
dir="ltr" aria-describedby="description-id-588180"
data-sessionlink="ei=6t2FVJLtEsOWrAbQ24HYAg&ved=CAcQvxs&feature=c4-videos-u"
href="/watch?v=I2AcJG4112A&list=UUrtZO4nmCBN4C9ySmi013oA">
Zombie on Omegle!
</a>
Я пытаюсь сделать это со страницы YouTube, и одна из проблем заключается в том, что YouTube не указывает тег или атрибут для заголовков своих ссылок, если это имеет смысл.
Вот что я пробовал:
import lxml.html
from lxml import etree
import urllib
url = 'https://www.youtube.com/user/makemebad35/videos'
response = urllib.request.urlopen(url)
content = response.read()
doc = lxml.html.fromstring(content)
tree = lxml.etree.HTML(content)
parser = etree.HTMLParser()
href_list = tree.xpath('//a/@href')
#Perfect. List of all url's under the 'href' attribute.
href_res = [lxml.etree.tostring(href) for href in href_list]
#^TypeError: Type 'lxml.etree._ElementUnicodeResult' cannot be serialized.
#So I tried extracting the 'a' tag without the attribute 'href'.
a_list = tree.xpath('//a')
a_res = [lxml.etree.tostring(clas) for clas in a_list]
#^This works.
links_fail = lxml.html.find_rel_links(doc,'href')
#^I named it 'links_fail because it doesn't work: the list is empty on output.
# But the 'links_success' list below works.
urls = doc.xpath('//a/@href')
links_success = [link for link in urls if link.startswith('/watch')]
links_success
#^Out: ['/watch?v=K_yEaIBByFo&list=UUrtZO4nmCBN4C9ySmi013oA', ...]
#Awesome! List of all url's that begin with 'watch?v=..."
#Now only if I could get the titles of the links...
contents = [text.text_content() for text in urls if text.startswith('/watch')]
#^Empty list.
#I thought this paragraph below wouldn't work,
# but I decided to try it anyway.
texts_fail = doc.xpath('//a/[@href="watch"]')
#^XPathEvalError: Invalid expression
#^Oops, I made a syntax error there. I forgot a '/' before 'watch'.
# But after correcting it (below), the output is the same.
texts_fail = doc.xpath('//a/[@href="/watch"]')
#^XPathEvalError: Invalid expression
texts_false = doc.xpath('//a/@href="watch"')
texts_false
#^Out: False
#^Typo again. But again, the output is still the same.
texts_false = doc.xpath('//a/@href="/watch"')
texts_false
#^Out: False
target_tag = ''.join(('//a/@class=',
'"yt-uix-sessionlink yt-uix-tile-link spf-link ',
'yt-ui-ellipsis yt-ui-ellipsis-2"'))
texts_html = doc.xpath(target_tag)
#^Out: True
#But YouTube doesn't make attributes for link titles.
texts_tree = tree.xpath(target_tag)
#^Out: True
#I also tried this below, which I found in another stackoverflow question.
#It fails. The error is below.
doc_abs = doc.make_links_absolute(url)
#^Creates empty list, which is why the rest of this paragraph fails.
text = []
text_content = []
notText = []
hasText = []
for each in doc_abs.iter():
if each.text:
text.append(each.text)
hasText.append(each) # list of elements that has text each.text is true
text_content.append(each.text_content()) #the text for all elements
if each not in hasText:
notText.append(each)
#AttributeError Traceback (most recent call last)
#<ipython-input-215-38c68f560efe> in <module>()
#----> 1 for each in doc_abs.iter():
# 2 if each.text:
# 3 text.append(each.text)
# 4 hasText.append(each) # list of elements that has text each.text is true
# 5 text_content.append(each.text_content()) #the text for all elements
#
#AttributeError: 'NoneType' object has no attribute 'iter'
У меня нет идей. Кто-нибудь хочет помочь этому питоновому падавану? :П
-----РЕДАКТИРОВАТЬ-----
Я на шаг впереди благодаря theSmallNothing
. Эта команда получает текстовые элементы:
doc.xpath('//a/text()')
К сожалению, эта команда возвращает много пробелов и новых строк ('\n') в качестве значений. Я, вероятно, опубликую еще один вопрос позже по этой проблеме. Если я это сделаю, я поставлю ссылку на этот вопрос здесь на случай, если кто-то еще с таким же вопросом окажется здесь.
Как использовать lxml для сопряжения "URL-ссылок" с "именами" ссылок (например, {name: link})