Найти и добавить каждую ссылку на ссылку HTML - Python - PullRequest
1 голос
/ 07 марта 2011

У меня есть HTML-файл, полученный из Википедии, и я хотел бы найти каждую ссылку на странице, например /wiki/Absinthe, и заменить ее текущим каталогом, добавленным вперед, например /home/fergus/wikiget/wiki/Absinthe, поэтому для:

<a href="/wiki/Absinthe">Absinthe</a>

становится:

<a href="/home/fergus/wikiget/wiki/Absinthe">Absinthe</a>

, и это по всему документу.

У вас есть идеи?Я счастлив использовать BeautifulSoup или Regex!

Ответы [ 5 ]

2 голосов
/ 07 марта 2011

Если это действительно все, что вам нужно сделать, вы можете сделать это с помощью sed и его опции -i, чтобы перезаписать файл на месте:

sed -e 's,href="/wiki,href="/home/fergus/wikiget/wiki,' wiki-file.html

Однако, вот решение Python, использующее прекрасный lxml API, на случай, если вам нужно сделать что-то более сложное, или у вас может быть плохо сформированный HTML и т. Д.:

from lxml import etree
import re

parser = etree.HTMLParser()

with open("wiki-file.html") as fp:
    tree = etree.parse(fp, parser)

for e in tree.xpath("//a[@href]"):
    link = e.attrib['href']
    if re.search('^/wiki',link):
        e.attrib['href'] = '/home/fergus/wikiget'+link

# Or you can just specify the same filename to overwrite it:
with open("wiki-file-rewritten.html","w") as fp:
    fp.write(etree.tostring(tree))

Обратите внимание, что lxml, вероятно, является лучшим вариантом, чем BeautifulSoup, для такого рода задач в настоящее время по причинам , указанным автором BeautifulSoup.

1 голос
/ 07 марта 2011

Это решение с использованием модуля re:

#!/usr/bin/env python
import re

open('output.html', 'w').write(re.sub('href="http://en.wikipedia.org', 'href="/home/fergus/wikiget/wiki/Absinthe', open('file.html').read()))

Вот еще одно без использования re:

#!/usr/bin/env python
open('output.html', 'w').write(open('file.html').read().replace('href="http://en.wikipedia.org', 'href="/home/fergus/wikiget/wiki/Absinthe'))
1 голос
/ 07 марта 2011

Вы можете использовать функцию с re.sub:

def match(m):
    return '<a href="/home/fergus/wikiget' + m.group(1) + '">'

r = re.compile(r'<a\shref="([^"]+)">')
r.sub(match, yourtext)

Пример:

>>> s = '<a href="/wiki/Absinthe">Absinthe</a>'
>>> r.sub(match, s)
'<a href="/home/fergus/wikiget/wiki/Absinthe">Absinthe</a>'
0 голосов
/ 07 марта 2011
from lxml import html

el = html.fromstring('<a href="/wiki/word">word</a>')
# or `el = html.parse(file_or_url).getroot()`

def repl(link):
    if link.startswith('/'):
       link = '/home/fergus/wikiget' + link
    return link

print(html.tostring(el))
el.rewrite_links(repl)
print(html.tostring(el))

Выход

<a href="/wiki/word">word</a>
<a href="/home/fergus/wikiget/wiki/word">word</a>

Вы также можете использовать функцию lxml.html.rewrite_links() напрямую:

from lxml import html

def repl(link):
    if link.startswith('/'):
       link = '/home/fergus/wikiget' + link
    return link

print html.rewrite_links(htmlstr, repl)
0 голосов
/ 07 марта 2011

Я бы сделал

import re

ch = '<a href="/wiki/Absinthe">Absinthe</a>'

r = re.compile('(<a\s+href=")(/wiki/[^"]+">[^<]+</a>)')

print ch
print
print r.sub('\\1/home/fergus/wikiget\\2',ch)

EDIT:

сказано, что это решение не захватывает теги с дополнительным атрибутом. Я думал, что это был узкий образец строки, такой как <a href="/wiki/WORD">WORD</a>

Если нет, то нет проблем, решение с более простым RE легко написать

r = re.compile('(<a\s+href="/)([^>]+">)')

ch = '<a href="/wiki/Aide:Homonymie" title="Aide:Homonymie">'
print ch
print r.sub('\\1home/fergus/wikiget/\\2',ch)

или почему бы и нет:

r = re.compile('(<a\s+href="/)')

ch = '<a href="/wiki/Aide:Homonymie" title="Aide:Homonymie">'
print ch
print r.sub('\\1home/fergus/wikiget/',ch)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...