Это структура HTML-документа, который мне нужно проанализировать (см. ОБНОВЛЕНИЕ 3):
<div id="txt_123_C01" style="position:absolute; left:5px; top:206px; width:532px; height:8912px;">
<div class="Normal-P1">
<span class="Normal-C2">Main title 1<br></span></div>
<div class="Normal-P1">
<span class="Normal-C3">Optional Subtitle<br></span></div>
<div class="Normal-P1">
<span class="Normal-C3">Second Optional Subtitle</span>
<span class="Normal-C4">Text blurb 1.<br></span></div>
<div class="Normal-P1">
<span class="Normal-C4">Text blurb 2.<br></span></div>
<div class="Normal-P1">
<span class="Normal-C4">Text blurb 4.<br></span></div>
<span class="Normal-C4"><br></span></div>
<div class="Normal-P1">
<span class="Normal-C3"><br></span></div>
<div class="Normal-P1">
<span class="Normal-C2">Main title 2<br></span></div>
<div class="Normal-P1">
<span class="Normal-C3">Subtitle 1</span>
<span class="Normal-C4"> Other text blurb 1.<br></span></div>
<div class="Normal-P1">
<span class="Normal-C4"> Other text blurb 2.<br></span></div>
Я хочу создать CSV, который выглядит следующим образом:
Main Title Optional Subtitle 1 Optional Subtitle 2 Text Blurb
---------- ------------------- ------------------- ------------------------
Main title 1 Optional Subtitle Second Optional Subtitle Text blurb1. Textblurb2. Text blurb 4.
Main Title 2 Subtitle 1 Other text blurb 2.
Я попытался:
soup = BeautifulSoup(page,'xml')
divText = soup.find_all('div', {'class':'Normal-P1'})
for item in divText:
spanTitle = soup.find_all('span',{'class':'Normal-C2'})
spanOptopnal = soup.find_all('span',{'class':'Normal-C3'})
Однако этот подход не позволяет мне выделить классы Normal-P1
так, чтобы я перешел с C2
на C4
и затем начал снова.C3
между C4
и следующим C2
не всегда существует.В этих случаях C4
является последним тегом перед следующим C2
.
Я рассмотрел вопрос о включении всех div
в список, а затем разбил их на подсписки на основе C2
для их обработки.Я пытаюсь выяснить, есть ли более элегантное решение с использованием bs4.
ОБНОВЛЕНИЕ 1
Возвращаясь к этому через некоторое время.Я только что просмотрел свой вывод, используя ответ ниже, и обнаружил проблему.
Глядя на
titles = soup.select(".Normal-P1 .Normal-C2")
for entry in titles:
print "entry:",entry
parent = entry.parent
print "parent: ",parent
subtitles = [
subtitle.text for subtitle in
parent.select(' ~ .Normal-P1 .Normal-C3')
]
print "subtitles:",subtitles
Я считаю, что subtitles
содержит результаты извне родителя (т. Е. Все titles
).Вывод выглядит следующим образом:
entry: <span class="Normal-C2">Main title 1<br/></span>
parent: <div class="Normal-P1">
<span class="Normal-C2">Main title 1<br/></span></div>
subtitles: [Optional Subtitle,Second Optional Subtitle,Subtitle 1]
entry: <span class="Normal-C2">Main title 2<br/></span>
parent: <div class="Normal-P1">
<span class="Normal-C2">Main title 2<br/></span></div>
subtitles: [Subtitle 1]
ОБНОВЛЕНИЕ 2
parent.select(" ~ .Normal-P1 .Normal-C3")
, кажется, вызывает проблему.
Проблема здесь в HTML, предоставленном в решении: <span class="Normal-C4"><br></span> </div>
.Отсутствует <div class="Normal-P1">
и закрывающий </div>
в конце.При внесении этих изменений я вижу ту же проблему (все субтитры в документе отображаются для записи) и в этом примере HTML.
Я дважды проверил отступ, и это выглядит нормально для меня.Что я делаю неправильно?
ОБНОВЛЕНИЕ 3
Это полный HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<div id="txt_123_C01" style="position:absolute; left:5px; top:206px; width:532px; height:8912px;">
<div class="Normal-P1">
<span class="Normal-C2">Main title 1<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C3">Optional Subtitle<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C3">Second Optional Subtitle</span>
<span class="Normal-C4">Text blurb 1.<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C4">Text blurb 2.<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C4">Text blurb 4.<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C4"><br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C3"><br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C2">Main title 2<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C3">New Subtitle 1</span>
<span class="Normal-C4"> Other text blurb 1.<br></span>
</div>
<div class="Normal-P1">
<span class="Normal-C4"> Other text blurb 2.<br></span>
</div>
</div>
</body>
</html>
Это вывод, который я вижу
entry: <span class="Normal-C2">Main title 1<br/></span>
parent: <div class="Normal-P1">
<span class="Normal-C2">Main title 1<br/></span>
</div>
subtitle: <span class="Normal-C3">Optional Subtitle<br/></span>
subtitle: <span class="Normal-C3">Second Optional Subtitle</span>
subtitle: <span class="Normal-C3"><br/></span>
subtitle: <span class="Normal-C3">New Subtitle 1</span>
entry: <span class="Normal-C2">Main title 2<br/></span>
parent: <div class="Normal-P1">
<span class="Normal-C2">Main title 2<br/></span>
</div>
subtitle: <span class="Normal-C3">New Subtitle 1</span>
Этомой код в настоящее время:
file = filepath + "test-page.html"
parser = HTMLParser.HTMLParser()
pageFile = codecs.open(file, 'r', encoding='utf-8')
pageRaw = pageFile.read()
page = parser.unescape(pageRaw)
soup = bs4.BeautifulSoup(page,'lxml')
titles = soup.select(".Normal-P1 .Normal-C2")
for entry in titles:
print "entry:",entry
parent = entry.parent
print "parent: ",parent
for subtitle in parent.select(" ~ .Normal-P1 .Normal-C3"):
print "subtitle:", subtitle