Навлизане по-дълбоко с xpath node()

Опитвам се да намеря заобикалящия текст на всички хипервръзки в абзаци на страници на Уикипедия и начинът, по който го правя, включва използването на xpath tree.xpath("//p/node()"). Нещата работят добре на повечето връзки и мога да намеря повечето неща, които са <Element a at $mem_location$>. Въпреки това, ако хипервръзката е в курсив (вижте примера по-долу), xpath node() я вижда само като <Element i at $mem_location> и не изглежда по-дълбоко.

Това кара моя код да пропуска хипервръзки и обърква индексирането на останалата част от страницата.

Ex:

<p>The closely related term, <a href="/bg/wiki/title="Mange">mange</a>,
is commonly used with <a href="/bg/wiki/Domestic_animal" title="Domestic animal" class="mw-redirect">domestic animals</a> 
(pets) and also livestock and wild mammals, whenever hair-loss is involved. 

<i><a href="/bg/wiki/Sarcoptes" title="Sarcoptes">Sarcoptes</a></i> 
and <i><a href="/bg/wiki/Demodex" title="Demodex">Demodex</a></i> 
species are involved in mange, both of these genera are also involved in human skin diseases (by 
convention only, not called mange). <i>Sarcoptes</i> in humans is especially 
severe symptomatically, and causes the condition known as 
<a href="/bg/wiki/Scabies" title="Scabies">scabies</a>.</p>

node() хваща правилно „Mange“, „Domastic animal“ и „Scabies“, но почти пропуска „Sarcoptes“ и „Demodex“ и прецаква индексирането, тъй като филтрирам възли, които са <Element a at $mem_location$>, а не <Element i at $mem_location$>.

Има ли начин да погледнете по-дълбоко с node()? Не можах да намеря нищо в документацията за това.

Редактиране: Моят xpath е "//p/node()" в момента, но хваща само най-външния елементен слой. През повечето време е <a>, което е страхотно, но ако е обвито в слой <i>, грабва само това. Питам дали има начин да проверя по-задълбочено, за да мога да намеря <a> в обвивката <i>.

Съответният код е по-долу: дърво = etree.HTML(четене)

titles = list(tree.xpath('//p//a[contains(@href,\"/wiki/\")]/@title')) #extracts the titles of all hyperlinks in section paragraphs
hyperlinks = list(tree.xpath('//p//a[contains(@href,\"/wiki/\")]/text()'))
b = list(tree.xpath("//p/b/text()")) #extracts all bolded words in section paragraphs
t = list(tree.xpath("//p/node()"))

b_count = 0
a_count = 0
test = []
for items in t:
print items
items = str(items)
if "<Element b" in str(items):
  test.append(b[b_count])
  b_count += 1
  continue
if "<Element a" in str(items):
  test.append((hyperlinks[a_count],titles[a_count]))
  a_count +=1
  continue

if "<Element " not in items:
  pattern = re.compile('(\t(.*?)\n)')
  look = pattern.search(str(items))

  if look != None: #if there is a match
    test.append(look.group().partition("\t")[2].partition("\n")[0])

  period_pattern = re.compile("(\t(.*?)\.)")
  look_period = period_pattern.search(str(items))
  if look_period != None:
    test.append(look_period.group().partition("\t")[2])

person Try431    schedule 18.06.2015    source източник
comment
Какъв е кодът, който използвате досега?   -  person Anand S Kumar    schedule 18.06.2015
comment
В променливата t искате всички елементи b и a? какво точно искате в променливата t?   -  person Anand S Kumar    schedule 18.06.2015
comment
t съдържа всички елементи, които са анализирани от xpath, така че това е списък на всичко, което е в параграфа. По-долу е print t[:15] [<Element b at 0x7f59228cf248>, ' is an ', <Element a at 0x7f5922947368>, ' with ', <Element a at 0x7f59229473b0>, '.', <Element sup at 0x7f59228cf2d8>, '\n', 'There are several complications with the terminology:\n', 'Acariasis is a term for a ', <Element a at 0x7f5922947440>, ', caused by mites, sometimes with a papillae (', <Element a at 0x7f59228cf3b0>, '), and usually accompanied by severe ', <Element a at 0x7f5922947488>]   -  person Try431    schedule 18.06.2015


Отговори (1)


Не мога да се сетя за директен xpath, който може да свърши работа, но винаги можете да преминете през съдържанието и да филтрирате елементите по този начин -

for i,x in enumerate(t):
    if x.tag == i:
        aNodes = x.find('a')
        if aNodes is not None and len(aNodes) > 0:
            del t[i]
            for j, y in enumerate(x.findall('/nodes()')): #doing x.findall to take in text elements as well as a elements.
                t.insert(i+j,y)

Това също би обработило множество a в един i, като <i><a>something</a><a>blah</a></i>

person Anand S Kumar    schedule 18.06.2015