1

Web ページhttp://subscribe.ru/catalog?rssからアンカー内のすべてのテキストを出力する非常に簡単なタスクがあります。これは私のコードです:

# encoding: utf-8
from lxml import etree

import urllib2
from lxml.html import document_fromstring

data = urllib2.urlopen('http://subscribe.ru/catalog?rss')
S=data.read()

oHTML = document_fromstring(S)
loLinks = oHTML.xpath("//a")

for oLink in loLinks:
    print etree.tostring(oLink)
    sLink = oLink.xpath('string()')[0]

出力は次のとおりです。

C:\Development\Python27\python.exe "D:/Topic Modeling/Playground/delme3.py"
Traceback (most recent call last):
  File "D:/Topic Modeling/Playground/delme3.py", line 15, in <module>
<a onclick="rgNav('js_tab_auth');return false;" href="">&#247;&#200;&#207;&#196; &#206;&#193; &#211;&#193;&#202;&#212;</a>
    sLink = oLink.xpath('string()')[0]
<a onclick="rgNav('js_tab_reg');return false;" href="">&#242;&#197;&#199;&#201;&#211;&#212;&#210;&#193;&#195;&#201;&#209; </a>
IndexError: string index out of range
<a class="forgot_pass" href="/member/totalrecall">&#250;&#193;&#194;&#217;&#204;&#201; &#208;&#193;&#210;&#207;&#204;&#216;?</a>

<a class="button_blue_2" id="js_loginFormBut" href="#">&#247;&#207;&#202;&#212;&#201;</a>

<a class="font_gray link_txd" href="/faq/vereinbarung.html">&#213;&#211;&#204;&#207;&#215;&#201;&#209; &#208;&#207;&#204;&#216;&#218;&#207;&#215;&#193;&#206;&#201;&#209; &#211;&#197;&#210;&#215;&#201;&#211;&#207;&#205; Subscribe.ru</a>
<a class="button_blue_2" id="js_regFormBut" href="#">&#238;&#193;&#222;&#193;&#212;&#216; &#210;&#197;&#199;&#201;&#211;&#212;&#210;&#193;&#195;&#201;&#192;</a>

<a class="rg_btn_soc rg_bs_01 js_tap_panel_selector" action="auth_email" href="#"><span><i/>Email</span></a>

<a class="rg_btn_soc rg_bs_01 js_tap_panel_selector" action="auth_openid" href="#"><span><i/>OpenID</span></a>

<a class="rg_btn_soc rg_bs_02 js_tap_panel_selector" action="auth_vkontakte" href="#"><span><i/>&#247;&#203;&#207;&#206;&#212;&#193;&#203;&#212;&#197;</span></a>

<a class="rg_btn_soc rg_bs_02 js_tap_panel_selector" action="auth_mailru" href="#"><span><i/>Mail.Ru</span></a>
 {#/if}
 {#if $P.login_register_tab == 2}

<a class="rg_btn_soc rg_bs_01 js_tap_panel_selector" action="reg_email" href="#"><span><i/>Email</span></a>

<a class="rg_btn_soc rg_bs_01 js_tap_panel_selector" action="reg_openid" href="#"><span><i/>OpenID</span></a>

<a class="rg_btn_soc rg_bs_02 js_tap_panel_selector" action="reg_vkontakte" href="#"><span><i/>&#247;&#203;&#207;&#206;&#212;&#193;&#203;&#212;&#197;</span></a>

<a class="rg_btn_soc rg_bs_02 js_tap_panel_selector" action="reg_mailru" href="#"><span><i/>Mail.Ru</span></a>
 {#/if}

<a href="" onclick="return false;">&#242;&#197;&#199;&#201;&#211;&#212;&#210;&#193;&#195;&#201;&#209;</a>
<a href="" onclick="ajax_recall_code();return false">&#247;&#217;&#211;&#204;&#193;&#212;&#216; &#197;&#221;&#197; &#210;&#193;&#218;</a>
<a href="#" class="button_blue_2" id="js_confirmFormBut">&#231;&#207;&#212;&#207;&#215;&#207;</a>

<a class="green" href="http://subs.link.subscribe.ru/422433"><strong>&#242;&#197;&#218;&#213;&#204;&#216;&#212;&#193;&#212;&#217; &#207;&#206;&#204;&#193;&#202;&#206; &#207;&#208;&#210;&#207;&#211;&#193;: "&#243;&#208;&#193;&#205; &#201;&#204;&#201; &#206;&#197; &#211;&#208;&#193;&#205;? &#247;&#207;&#212; &#215; &#222;&#197;&#205; &#215;&#207;&#208;&#210;&#207;&#211;!"</strong></a> 


<a title="Subscribe.Ru" href="/" class="logo"><dfn class="logokanal"/></a>


Process finished with exit code 1

ということで、リンクは抽出されましたが、リンクテキストがなぜか抽出できませんでした。出力は、エンコーディングに何らかの問題があることを示唆しています (cite コンテンツは人間が読めるテキストのみで構成されています)。どうすればこれを修正できますか?

utf-8 を使用してデコードしようとしてもうまくいきませんでした:

# encoding: utf-8
from lxml import etree
import urllib2
import chardet
from lxml import html

data = urllib2.urlopen('http://subscribe.ru/catalog?rss')
S=data.read()

encoding = chardet.detect(S)['encoding']
print encoding
if encoding != 'utf-8':
    S = S.decode(encoding,'replace').encode('utf-8')

oHTML = html.fromstring(S)
loLinks = oHTML.xpath("//a")

for oLink in loLinks:
    print etree.tostring(oLink)
    sLink = oLink.xpath('string()')[0]

同じエラーで失敗しました。

よろしくお願いします。

4

1 に答える 1

1

が得られますIndexError(問題はエンコーディングとは関係ありません)。

要素が空の場合<a>(およびそれらの一部がその Web ページ上にある場合)、oLink.xpath('string()')コードでは空のリストが返されます。そして、oLink.xpath('string()')[0]あなたにIndexError.

次のコードは、あなたが望むものを提供します(私は思います)。HTML ページは KOI8-R でエンコードされています。lxml を使用して URL から直接解析できることに注意してください。

from lxml import html

URL = 'http://subscribe.ru/catalog?rss'

parser = html.HTMLParser(encoding="KOI8-R")
content = html.parse(URL, parser)
anchors = content.xpath("//a")

for anchor in anchors:
    text = anchor.text
    if text:  # if the anchor is not empty
        print text.encode("utf-8")

このプログラムからの出力は次で始まります。

Вход на сайт
Регистрация 
Забыли пароль?
Войти
условия пользования сервисом Subscribe.ru
Начать регистрацию
Регистрация
Выслать еще раз
Готово

そして次で終わります:

Спорт
Прогноз погоды
Новости и СМИ
Страны и Регионы
Общество
Дом и семья
Все разделы
ЗАО «Интернет-Проекты»
于 2013-10-01T20:46:17.947 に答える