Python, найдите текст в строке сразу под известной строкой?

Я написал скрипт, используя модуль python BeautifulSoup, чтобы получить url = 'http://www.ebi.ac.uk/ena/data/view/PRJEB2357&display=xml' project_page = urlopen ( url ) soup = BeautifulSoup ( project_page , "html.parser" ) печатать суп с веб-страницы. Эта веб-страница содержит информацию, описывающую проект с использованием геномных данных, и я хочу извлечь все <db> PUBMED </ db> <id> 25101644 </ id> </ xref_link> </ project_link> <project_link> <xref_link> <db > PUBMED </ db> <id> 24509479 </ id> (уникальные идентификационные номера для публикаций, полученных из этого проекта). Каждый идентификатор PUBMED является 8-значным номером.

Я попробовал два разных метода для извлечения идентификаторов PUBMED, но есть проблемы с обоими. Во-первых, я использовал этот код для извлечения полного xml:

<id>

Результат этой команды выглядит примерно так:

url = 'http://www.ebi.ac.uk/ena/data/view/PRJEB2357&display=xml'
project_page = urlopen(url)
soup = BeautifulSoup(project_page, "html.parser") 
text = soup.text
print text

(очевидно, это не весь xml, а только раздел, который имеет отношение ко мне).

Модуль BeautifulSoup содержит ряд команд, которые просматривают этот суп для интересующего текста, но насколько я могу судить, все они берут либо тег, либо текст, который ищет в качестве входных данных. Я не могу использовать ни одно из них здесь, потому что на этой странице есть несколько сегментов текста, кроме PUBMED ID, которые имеют один и тот же тег xml ( ), и я явно не могу найти PUBMED ID, используя текст, если я Не знаю, что это такое!PUBMED 25101644 PUBMED 24509479

Второй метод, который я пытался, заключался в том, чтобы печатать только текст из xml с помощью этого кода:

url = 'http://www.ebi.ac.uk/ena/data/view/PRJEB2357&display=xml'
project_page = urlopen(url)
soup2 = BeautifulSoup(project_page, "html.parser") 
text = soup2.text
text = text.replace('
', ' ').replace(' ', '') #removes all spaces and linebreaks
PMID = re.findall('PUBMED........', text, flags = 0)
print PMID

На этот раз вывод выглядит следующим образом:

[u'PUBMED25101644', u'PUBMED24509479']

В этот момент у меня было несколько идей. Во-первых, модуль python re (регулярное выражение в более ранних версиях python) можно было бы использовать для поиска выражения, но снова все команды re, о которых я знаю, требуют, по крайней мере, части шаблона, который ищет в качестве входных данных, поэтому я не думаю, что это только вариант. Во-вторых, я попытался сделать что-то вроде этого:

print text
PUBMED
25101644




PUBMED
24509479

Это дает следующий результат:

>>> re.findall('(?<=PUBMED
).+',text)
['25101644', '24509479']

Поэтому теоретически это можно преобразовать в строку, и я просто вырезал соответствующие 8-значные числа, но это очень тяжело, и я хочу много раз запускать этот скрипт на веб-страницах для нескольких тысяч проектов и количество идентификаторов PUBMED для каждый проект будет меняться, поэтому этот метод не поддается автоматизации очень хорошо.

То, что я хочу, это метод поиска каждого экземпляра слова «PUBMED», либо в сыром супе, либо в тексте, и извлечение только идентификатора PUBMED, который будет на следующей строке вниз. Кто-нибудь есть предложения о том, как это сделать?

python,regex,xml,web-scraping,beautifulsoup,

1

Ответов: 3


0 принят

Вы можете напрямую использовать внешний вид выражения выражения. Если текст

.+

Используя

[d]+

Если вы хотите получить только цифры , которые следуют познаваемая строка замены PUBMEDс , и было бы выбрать только цифру.[pubmed.find_next_sibling("ID").get_text() for pubmed in soup.find_all("DB", text="PUBMED")]

Надеюсь это поможет.


1

Найдите все вхождения PUBMEDи получите следующих братьев и сестер :

search = lambda tag: tag.name == "ID" and tag.find_previous_sibling("DB", text="PUBMED")
print([pubmed.get_text() for pubmed in soup.find_all(search)])

Или выполните функцию поиска :

xml

Обратите внимание, что вы должны использовать xmlпарсер, а не html.parser:

soup = BeautifulSoup(project_page, "xml")

DEMO:

In [1]: from urllib2 import urlopen

In [2]: from bs4 import BeautifulSoup

In [3]: url = 'http://www.ebi.ac.uk/ena/data/view/PRJEB2357&display=xml'

In [4]: project_page = urlopen(url)

In [5]: soup = BeautifulSoup(project_page, "xml")

In [6]: [pubmed.find_next_sibling("ID").get_text() 
   ...:  for pubmed in soup.find_all("DB", text="PUBMED")]
Out[6]: [u'25101644', u'24509479']

In [7]: search = lambda tag: tag.name == "ID" and tag.find_previous_sibling("DB", text="PUBMED")

In [8]: [pubmed.get_text() for pubmed in soup.find_all(search)]
Out[8]: [u'25101644', u'24509479']

0

Вы можете найти, dbа затем получить свой первый родной брат

data = '''<db>PUBMED</db>
<id>25101644</id>
</xref_link>
</project_link>
<project_link>
<xref_link>
<db>PUBMED</db>
<id>24509479</id>'''

from bs4 import BeautifulSoup
soup = BeautifulSoup(data, "html.parser")
#print(soup)

for x in soup.find_all('db'):
    print(x.text, x.fetchNextSiblings()[0].text)

результат

PUBMED 25101644
PUBMED 24509479
питон, регулярное выражение, XML, Web-соскоб, BeautifulSoup,
Похожие вопросы